a#acchi base: buffer overflow - people.unica.it · ebp-0xf sul registro eax, muove il contenuto...
TRANSCRIPT
Pattern Recognition and Applications Lab
Università
di Cagliari, Italia
Dipartimento di Ingegneria Elettrica
ed Elettronica
A#acchiBase:BufferOverflow
Do#.Ing.DavideMaiorca,Ph.D.
CorsodiSicurezzaInforma<ca–A.A.2015/2016
http://pralab.diee.unica.it
Sommario
• Introduzione• AnalisidiunProgrammaVulnerabile– AltriElemen<Assembly– Analisifunzioni
• Exploi8ng– Analisidellostackvulnerabile– A#accoallostack– Contromisure
http://pralab.diee.unica.it
Introduzione–Vulnerabilità
• Finoraabbiamoanalizzatouneseguibilesenzapossederneilsuosorgente
• Laprossimadomandaè:cherelazionehailreverseengineeringconlasicurezza?
• Una*accantepuòanalizzareuneseguibilealfineditrovaredellevulnerabilità
• UnavulnerabilitàèunerrorediprogrammazioneilcuisfruEamentopuòportareadunaviolazionediintegritàeconfidenzialitàdiunsistema– Sonostatedatetantedefinizionidivulnerabilità(ISO,NIST,ENISA…)
• Avetegiàvistodegliesempi…– CrossSiteScrip<ng– SQLInjec<on
• Inquestalezioneanalizzeremolavulnerabilità«regina»legataall’esecuzionediunprogramma,ovveroilbufferoverflow
http://pralab.diee.unica.it
Introduzione–BufferOverflow
• Vulnerabilitàconcernentelages:onedellamemoriae,inpar8colare,unacaRvages8onedellostack
• PotetegiàimmaginaredicosasitraRdalnome…• Unbufferèunazonadimemoriapensataperconteneredeida8• Lapar8colaritàdiquestazonaècheladimensionedeida8èprefissata• L’esempiopiùclassicodibufferè,adesempio,unarray• Unoverflowaccadequandoinseriamodeida8chesuperanolacapacità
delbuffer– Banalmente:inseriteinmemoriaunastringadi5caraEeriinunbufferdi4caraEeri…
charstr[3]
CIAOO-> CIAOOOVERFLOW!
http://pralab.diee.unica.it
Challenge!
• Apriteilprogramma«invincibile»• Doveteindovinareilcodicesegreto!• Mal’impresanonsembracosìsemplice…• Per«sconfiggere»ilprogramma«invincibile»ciserveuncambiodi
prospe=va…• Chiediamoci:ilprogrammaèsicuro?• Inquestalezioneimpareretecosapuòsuccederequandounprogramma
èvulnerabileadunbufferoverflow…– Inpar8colare,imparereteasfruEareunbufferoverflowavostrovantaggio…– Ancheiprogrammiinvincibili(mainsicuri…)possonoesseresconfiR!
http://pralab.diee.unica.it
DISCLAIMER
IVALORIDEIREGISTRI(ebp,esp,eax…)POSSONOESSEREDIVERSIASECONDADELLAVOSTRA
ARCHITETTURAEVENGONORIPORTATISULLESLIDESQUELLIOTTENUTIDALLAMACCHINAVIRTUALEUSATAALEZIONE
http://pralab.diee.unica.it
AnalisiProgramma(primaocchiata)
• Ilprogrammavichiedediinserireuncodicedimassimo3cifre…• Notatecomeilcodicesiasempreerrato(amenodiclamorosicolpidi
fortuna…)• Ilmassimodi3cifredovrebbestuzzicarvi…
– Cosasuccedeseinseritepiùdi3cifre?
• Proviamocon5-10cifre…– Apparentementenonsuccedeniente…
• Adessoproviamocon15cifre…– Perdetecomunque…– Mariceveteunerroredisegmenta8onfault!
• Segmenta8onfaultavvienequandoilprogrammatentadiscriveredeida8inmemoriainsegmen8nonper:nen:– Adesempio,tentodiscrivereinunsegmentochenondisponedelflagw– Questoerrorenondovrebbemaicomparire…– E’ilprimoindiziocheilprogrammapossaesserevulnerabile!
http://pralab.diee.unica.it
AnalisiSta<caProgramma
• Vediamodidisassemblarel’eseguibile– objdump–dinvincible
• Comeprima,cerchiamodiindividuaredellefunzionicheabbianodeinomiinteressan:…– main– inserire_codice– genera_codice– win– lose
• Adessoguardiamolafunzionemain,inpar8colarelechiamatecall– Vediamoquest’ordinedichiamate:
• genera_codice• puts• inserire_codice• win• lose
http://pralab.diee.unica.it
Elemen<diAssemblyX86(2)
• Altreistruzioni– JMP<offset>:Saltononcondizionato– CMP:Confrontaicontenu<didueregistri(oregis<ememoria)edimpostaunflag
specialea1seidueelemen<hannolostessovalore– JNE<offset>(disolitoaccoppiatoconcmp):saltaall’offsetseilflagspecialeè
impostatoazero(quindiseidueelemen<confronta<concmpnonsonouguali)– JEQ<offset>(disolitoaccoppiatoconcmp):saltaall’offsetseilflagspecialeè
impostatoauno(quindiseidueelemen<confronta<concmpsonouguali)– LEAaddress,register:caricaunindirizzodimemoriasuunregistro– SAR,n_bit,reg:esegueunoshiedinbitsulvaloredelregistroreg– IMUL,reg,value:mol<plicailvalorecontenutodiunregistroperunvaloreintero
http://pralab.diee.unica.it
AnalisiMain(1)
• Naturalmente,guardarelasequenzadichiamatenonèsufficiente!
08048597<main>:8048597:push%ebp8048598:mov%esp,%ebp804859a:and$0xfffffff0,%esp804859d:sub$0x20,%esp80485a0:call8048521<genera_codice>80485a5:mov%eax,0x18(%esp)80485a9:movl$0x80486ac,(%esp)80485b0:call80483a0<puts@plt>80485b5:call80484fd<inserire_codice>80485ba:mov%eax,0x1c(%esp)…
Preparalachiamatadifunzioni
Chiama<genera_codice>esalvailrisultatonellostack(suesp+0x18)
Memorizzalastringaparametronellostackechiamaputssuquellastringa
Chiama<inserire_codice>ememorizzailrisultatonellostack(suesp+0x1c)
http://pralab.diee.unica.it
AnalisiMain(2)
• Naturalmente,guardarelasequenzadichiamatenonèsufficiente!
80485be:mov0x1c(%esp),%eax80485c2:cmp0x18(%esp),%eax80485c6:jne80485cf<main+0x38>80485c8:call804856f<win>80485cd:jmp80485d4<main+0x3d>80485cf:call8048583<lose>80485d4:mov$0x0,%eax
Confrontailrisultatodi<inserire_codice>(messosueax)e<genera_codice>(presodallostack)
Seilrisultatodelconfrontononèparia1(quindiidueelemen8sonouguali),vaiallafunzioneloseALTRIMENTICONTINUAL’ESECUZIONEconwineSALTAALL’ULTIMAmov(E’sostanzialmentel’equivalentediunif-elseinC,soltantoespressoinmanieraleggermentediversa)
http://pralab.diee.unica.it
Funzioniwinelose
• Quindi:ilmainchiamaduefunzionicheres8tuisconoduevalori• Ques8valorivengonoconfronta8• Easecondadelconfrontovengonochiamateduefunzionidiverse!• Consideratoilfunzionamentodelprogramma,possiamosupporrechese
ilcodiceècorreEovienechiamatawin,altrimen8lose• Osserviamol’assemblydellefunzioniwinelose• Sostanzialmentesonodueputs!• Quindilefunzioniwinelosesioccupanodistampareunmessaggioa
video!• winagiscesullastringaall’indirizzo0x8048670,mentreloseagiscesulla
stringaall’indirizzo0x804868c
http://pralab.diee.unica.it
Dumpstringhe
• Eseguiteobjdump–sinvicible.Potetevederequellocheè,fondamentalmente,l’hexdumpdelfileraggruppatopersezioni
Contenutodellasezione.rodata:804866803000000010002004861692076696e74........Haivint80486786f2120436f6469636520636f72726574o!Codicecorret8048688746f210048616920706572736f212049to!.Haiperso!I80486986c20636f6469636520c3a82065727261lcodice..erra80486a8746f2100496e73657269726520636f64to!.Inserirecod80486b869636520286d617373696d6f20332063ice(massimo3c80486c8696672652e2e2e293a00ifre...):.
Indirizzoprimobytedellariga
0x8048670(stringafunzionewin)
0x804868c(stringafunzionelose)
Orasappiamocosastampanolefunzioniwinelose!Diconseguenza,nell’esecuzionedelprogrammaarriviamosempreallafunzionelose!
http://pralab.diee.unica.it
Funzionegenera_codice
• Restanodaanalizzaregenera_codiceedinserire_codice• genera_codiceèunafunzionemoltolunga!• NonnevedremoideEagliperragioniditempo…
– PotrestestudiarvelacomeesercizioJ
• Vengonochiamatelefunzioni8me,sranderand• Moltoprobabilmenteècoinvoltalagenerazionediunnumerocasuale…• …edeffeRvamenteèpropriocosì!• Generacodicegeneraunvalorecasualefra0e999(compresi)• Quindiognivoltacheeseguiteilprogrammailcodiceèsemprediverso!• Unpo’difficile,così,raggiungerelafunzionewin…• Amenodigrossicolpidifortuna,raggiungeretesemprelafunzionelose!• Amenoche…
http://pralab.diee.unica.it
Funzioneinserire_codice
• Cosapossiamodiredellafunzioneinserire_codice?
push%ebpmov%esp,%ebpsub$0x28,%esplea-0xf(%ebp),%eaxmov%eax,(%esp)call8048380<gets@plt>lea-0xf(%ebp),%eaxmov%eax,(%esp)call80483f0<atoi@plt>mov%eax,-0xc(%ebp)mov-0xc(%ebp),%eax
Liberamemoriaperlachiamatadifunzioni
Carical’indirizzodimemoriapuntatodaebp-0xfsulregistroeax,muoveilcontenutodieaxSULLALOCAZIONEPUNTATADAESP(aEenzionealleparentesisu%esp)echiamagets
Comepergets,maquestavoltavienechiamatalafunzioneatoi.Ilrisultatovienesalvatoinunavariabilelocale(lamov)evienepoi«ricaricato»nelregistroaccumulatore
http://pralab.diee.unica.it
Funzioneinserire_codice-StackStackFrame(Perlafunzioneinserirecodice)
ESP
…lea-0xf(%ebp),%eaxmov%eax,(%esp)Questaèl’esecuzionedellostackdopolamovprimadellachiamatadigets.Lostackèstato«accorciato»permo<vidispazio.Quandovienechiamatalagets,vieneinseritonellostack,comeparametro,l’indirizzodibasedell’array.L’arrayverràquindimemorizzatoapar<redaEBP-0xf.Notabene:nonèdeEochel’indirizzodipartenzadell’arraysianecessariamenteunmul8plodi4
EBPPrecedenteEBP
esp=0xbffff000ebp=0xbffff028ebp-0xf=0xbffff019
EBP–0xf
mainReturnADDRESS
…
EBP–0xf
http://pralab.diee.unica.it
Funzioneinserire_codice–Stack(2)StackFrame(Perlafunzioneinserirecodice)
ESP
…lea-0xf(%ebp),%eaxmov%eax,(%esp)call8048380<gets@plt>Quandogetsvienechiamata,l’utentedeveinseriredeicara#eridatas<era.Ilrisultatoèunarraydichar,incuiognicharècompostodaunbyte.Immaginiamochel’utenteinseriscalastringa«123»(l’arrayèstatodichiaratodatrecaraEerimal’utenteNONlosa).Ricordateviche,acausadelli#leendian,ilprimonumerocoprel’indirizzoINFERIOREdellostack…
EBP
esp=0xbffff000ebp=0xbffff028ebp-0xf=0xbffff019
EBP–0xf
mainReturnADDRESS
…
EBP–0xf 123
EBPPrecedente
0
http://pralab.diee.unica.it
Funzioneinserire_codice–Overflow!StackFrame(Perlafunzioneinserirecodice)
ESP
…lea-0xf(%ebp),%eaxmov%eax,(%esp)call8048380<gets@plt>Lafunzionegetsnoneffe#uaalcuncontrollosulladimensionedell’array.Cioèsignificachearraypiùgrandidelladimensionedichiaratapossonoesserescririnmemoria.Adesempio,questoècosasuccedeseinserite«123456».SIETELIBERIDIRIEMPIRELOSTACKAVOSTROPIACIMENTO.
EBP
esp=0xbffff000ebp=0xbffff028ebp-0xf=0xbffff019
EBP–0xf
mainReturnADDRESS
EBP–0xf 123456
…
EBPPrecedente
http://pralab.diee.unica.it
Funzioneinserire_codice–A#accoStackFrame(Perlafunzioneinserirecodice)
ESP
…lea-0xf(%ebp),%eaxmov%eax,(%esp)call8048380<gets@plt>Siamoliberidiriempirelostackcomevogliamo.Normalmentequestoporterebbeadeglierroridisegmenta<onfault…Macosasuccedessesefossimocosìbravidariempirelostackinmanieracontrollata,inmododasovrascrivereilreturnaddressconunaltroindirizzo?Potremmo,adesempio,saltaredireEamenteallafunzionewin…
Da<SovrascrirEBP
esp=0xbffff000ebp=0xbffff028ebp-0xf=0xbffff019
EBP–0xf
winAddress
EBP–0xf 123456
Da<Sovrascrir
http://pralab.diee.unica.it
All’a#acco!
• Nellapra8caquestoaEaccoèassolutamentepossibile…• gdbinvincible• break0*8048509
– Cis8amofermandoprimachelafunzionegetsvengachiamata
• Inforegistersebp– ebp=0xbffff028
• Sonoglistessivalorisegna8nelleslidepreceden8
• Dall’analisista8ca,sappiamochel’arrayiniziadaebp-0xf.• Perarrivarearidossodell’indirizzodiritorno,dobbiamoquindiriempire
lostackcon0xf(15)+4bytes=19bytes• L’aEualeindirizzodiritornositrovaadebp+4
– 0x080485ba(prossimaistruzionedelmain)
• ObieRvofinale:sos8tuirel’indirizzodiritornoconl’indirizzodiwin– Inquestoesempioè0x0804856f(dovetesovrascriverel’interoindirizzo!)
http://pralab.diee.unica.it
All’a#acco!(2)
• Quindi,quandogetsvirichiedediinserireida8…• DoveteprimadituEoinserire19bytes• Laprimapartedellastringapuòessere,adesempio,
1111111111111111111• Oradoveteassicurarvidiinserireinmemoriaibytespersovrascrivere
l’indirizzodiritorno– Doveteinserireibytesinquestomodo:\xByte– RispeEatelaliEleendianess(adueadue).PRIMAGLIULTIMIDUEVALORI,POII
PENULTIMIDUE,etc.– Quindi:\x6f\x85\x04\x08
• Lastringafinaledainseriredovrebbeessere:1111111111111111111\x6f\x85\x04\x08
• TuEavia,qualcosaancoranonva…• Seinseritequestastringa,avreteancorasegmenta8onfault…L
http://pralab.diee.unica.it
EXPLOIT!
• LaragioneèdaricercarsinelfaEocheilprogrammaprendeiningressodeicaraEeri– OgnivaloreesadecimalehaunatraduzioneincaraEeri…– Sfortunatamente,alcuninonpossonoessereinseri8datas8eraL
• Perovviarealproblema,civieneinaiutolafunzioneprintdellinguaggioperl• Poteteusarequestointerpretepertradurreinautoma8codegliesadecimali
incaraEerinoninseribilidall’utente• Unbuonmodoperfarequestoè:
– ScrivereicaraEerisuunfiletemporaneo– Almomentodell’esecuzione,direalprogrammaditrasferirelostandardinputdatas8eraa
file
• Quindi…chiudetegdbedeseguiteperl-e'print"1"x19;print"\x6f\x85\x04\x08";'>/tmp/input• ConperlsipossonofacilmenteripetereicaraEericon‘print«caraEere»*numero• Ogniistruzioneperlèseparata,comeilC,daunpuntoevirgola(statequindieseguendodue
istruzioni• >/tmp/inputscrivesufile
http://pralab.diee.unica.it
Comedifendersi?(inquestocaso)
• Questoèilcasopiùsemplicedibufferoverflow• Perdifendersi,bisognaevitarediu8lizzarefunzionichenoneffeEuanoil
controllosulladimensionedegliarray– gets– strcpy– sprinW– SonotuEefunzionivulnerabili!
• U8lizzate,invece,funzionicheeffeEuanoilcontrollosulladimensionedegliarray– fgets– strncpy– snprin�
• Inognicaso,compilatoricomegccviavvisanosestateusandodellefunzioni«vulnerabili»
http://pralab.diee.unica.it
Inconclusione…
• L’analisidiunaapplicazionevulnerabileconsentedieffeEuaredeipoten8aEacchi,comeilbufferoverflow
• TaliaEacchipossonofaravereall’applicazionedeicomportamen8«anomali»
• TuEavia,questoancoranonbasta…• Unbufferoverflowpiùavanzatopotrebbeessereusatopercreare
ancorapiùdanni…• …adesempio,puòconsen8rediprendereilcontrollodiunamacchina
Linux(oWindows)• NellaprossimalezionevedremounesempioditaleaEaccoed
esploreremotecnichedidifesapiùcomplesse