HTCinside


5 silumisvastast tehnikat, mis kaitsevad teie tarkvara

Tarkvaratoodete avaldamisel kirjutame kõik EULA-desse: 'Te ei tohi tarkvara pöördprojekteerida, dekompileerida ega lahti võtta'. Kuid paljudes olukordades ei ole sõnad parim kaitse ja teil on tõesti vaja kasutusele võtta mõned tehnilised tööriistad, et vältida tarkvara ümberpööramist ja kaitsta oma oskusteavet avalikustamise eest.

Tarkvara pöördprojekteerimise takistamiseks on mitu tehnoloogilist lähenemisviisi: silumisvastane, dump-vastane ja teised. Selles postituses keskendume mõnele silumisvastasele meetodile, kuna need on tagasipööramisvastase kaitse tuumaks. Siluri lisamine uuritavale protsessile selle samm-sammult täitmiseks on mis tahes tagurdamistöö väga oluline etapp – seega vaatame, milliseid tööriistu saame tagurdajate elu raskemaks muuta.

On paar asja, mida tahaksin kohe alguses mainida. Esimene on see, et tarkvara pöördprojekteerimise eest pole universaalset ega 100% kuulikindlat kaitset. Tagurdajale on alati võimalus sisse pääseda, ainus strateegia, mis meil on, on muuta tema töö võimalikult raskeks ja vaevanõudvaks.

Järgmiseks on olemas üsna palju pöördprojekteerimise ja eelkõige silumisvastaseid meetodeid, sealhulgas ajapõhine kaitse või isegi spetsiifilised koodiga manustatud tehnoloogiad, nagu nanomiidid. Selles postituses käsitleme ainult mitmeid Windowsi-põhiste süsteemide jaoks spetsiifilisi standardseid lähenemisviise, kõige populaarsemaid.

Allpool esitatud lähenemisviise kirjeldatakse üldiselt.

Sisu

Sisu

  1. Sisseehitatud funktsioonid siluri olemasolu kontrollimiseks
  2. Niidi peitmine
  3. Lipukontrollid
  4. Katkestuspunkti tuvastamine
  5. Erandi käsitlemine: SEH
  6. Järeldus

1 – sisseehitatud funktsioonid siluri olemasolu kontrollimiseks

Windowsi süsteemid pakuvad meile valmis tööriistad lihtsa silumisvastase kaitse loomiseks. Üks lihtsamaid silumisvastaseid tehnikaid põhineb funktsiooni IsDebuggerPresent kutsumisel. See funktsioon tagastab väärtuse TRUE, kui kasutajarežiimi silur silub praegu protsessi.

See funktsioon viitab PEB-le (Process Environment Block, suletud süsteemi struktuur) ja eriti selle väljale BeingDebugged. Tagurdajad kasutavad sellisest kaitsetehnikast mööda minnes seda fakti: nt. rakendades DLL-i süsti, seadistavad nad BeingDebugged väärtuseks 0 vahetult enne selle kontrollimist kaitstud koodis.

Paar sõna selle kohta, kus sellist kontrolli teha. Põhifunktsioon pole parim valik: tagurdajad kontrollivad seda tavaliselt kõigepealt lahtivõetud loendis. Parem on teha silumisvastane kontroll TLS-i tagasihelistamisfunktsioonis, kuna seda nimetatakse enne peamise käivitatava mooduli sisenemiskutsungit.

Veel üks funktsionaalse kontrolli valik on CheckRemoteDebuggerPresent. Erinevalt ülalkirjeldatud funktsioonist kontrollib see, kas mõni muu paralleelne protsess silub praegu protsessi. See põhineb funktsioonil NtQueryInformationProcess ja eelkõige ProcessDebugPort väärtusel.

2 – niidi peitmine

Kui eelmine meetodite rühm oli üles ehitatud siluri olemasolu kontrollimisele, siis see pakub selle eest aktiivset kaitset.

Alates operatsioonisüsteemist Windows 2000 saab funktsioon NtSetInformationThread uue lipu nimega ThreadHideFromDebugger. See on Windows OS-is pakutav väga tõhus silumisvastane tehnika. Selle lipuga lõim peatub silumissündmuste teavituste saatmiseks, sealhulgas katkestuspunktide ja muude kohta, varjates end siluri eest. ThreadHideFromDebuggeri seadistamine põhilõime jaoks muudab siluri lõime külge kinnitamise protsessi märkimisväärselt keerulisemaks.

Loogiline jätk võeti kasutusele Windows Vistas funktsiooniga NtCreateThreadEx. Sellel on parameeter CreateFlags, mis seadistab muu hulgas lipu THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. Selle lipukomplektiga protsess peidetakse siluri eest.

3 – lipukontrollid

Silumist saab tuvastada erinevate lippude muudetud väärtuste järgi erinevates süsteemi- ja protsessistruktuurides.

Windows NT sisaldab globaalset muutujat nimega NtGlobalFlag koos lippude komplektiga, mida kasutatakse süsteemi jälgimiseks ja silumiseks. Ülaltoodud PEB struktuur sisaldab oma NtGlobalFlag välja. Silumise ajal muudetakse seda välja väärtust mitme konkreetse lipu abil. Nende lippude kontrollimine võib käivitada silumisvastase kaitse.

Käivitatav fail saab lähtestada PEB-struktuuri NtGlobalFlag lipud spetsiaalse struktuuri abil nimega IMAGE_LOAD_CONFIG_DIRECTORY, mis sisaldab süsteemilaaduri konkreetseid konfiguratsiooniparameetreid. Sellel on väli GlobalFlagsClear, mis lähtestab PEB-i NtGlobalFlag lipud. Vaikimisi seda struktuuri käivitatavale failile ei lisata, kuid seda saab hiljem lisada. Asjaolu, et käivitatavas failis pole seda struktuuri või GlobalFlagsClear väärtus on 0, samas kui kettale või jooksva protsessi mällu salvestatud vastav väli ei ole null, näitab peidetud siluri olemasolu. Seda kontrolli saab rakendada käivitatavas koodis.

Teine lippude rühm on protsessihunnik. Vastavas _HEAP-struktuuris on kaks välja: Flags ja ForceFlags. Mõlemad muudavad oma väärtusi vastava protsessi silumisel ja võivad seega olla silumisvastase kontrolli ja kaitse aluseks.

Veel üks lipukontroll, mida saab kasutada siluri tuvastamiseks, on Trap Flag (TF) kontroll. See on EFLAGSi registris. Kui TF on 1, genereerib CPU pärast iga silumisprotsessi toetava käsu täitmist INT 01h ('Ühe sammu' erand).

4 – murdepunkti tuvastamine

Katkestuspunktid on mis tahes silumisprotsessi oluline osa ja seega saame nende tuvastamisel siluri tuvastada ja neutraliseerida. Murdepunkti tuvastamisel põhinev silumisvastane taktika on üks võimsamaid ja raskemini möödapääsetavaid.

Katkestuspunkte on kahte tüüpi: tarkvara ja riistvara.

Tarkvara murdepunktid määrab silur, sisestades koodi int 3h käsu. Seega põhinevad siluri tuvastamise meetodid vastava funktsiooni kontrollsumma arvutamisel ja juhtimisel.

Selle kaitse vastu võitlemiseks pole universaalset meetodit – häkker peab leidma kontrollsumma(d) arvutava koodilõigu ja asendama kõigi vastavate muutujate tagastatud väärtused.

Riistvara murdepunktid määratakse spetsiaalsete silumisregistrite abil: DR0-DR7. Neid kasutades saavad arendajad programmi täitmise katkestada ja juhtimise silurile üle anda. Silumisvastase kaitse saab üles ehitada nende registrite väärtuste kontrollimisele või olla ennetavam ja nende väärtused sunniviisiliselt lähtestada, et silumine peatada funktsiooni SetThreadContext abil.

5 – erandite käsitlemine: SEH

Struktureeritud erandite käsitlemine ehk SEH on mehhanism, mis võimaldab rakendusel saada teateid erandolukordade kohta ja käsitleda neid operatsioonisüsteemi asemel. Osutajad SEH-käsitlejatele nimetatakse SEH-raamideks ja paigutatakse virna. Kui erand luuakse, käsitleb seda virna esimene SEH-kaader. Kui see ei tea, mida sellega teha, edastatakse see virnas järgmisele ja nii edasi kuni süsteemihaldurini.

Kui rakendust silutakse, peaks silur pärast int 3-tunnist genereerimist kontrolli katkestama või SHE töötleja võtab selle. Seda saab kasutada silumisvastase kaitse korraldamiseks: saame luua oma SEH-käsitleja ja panna selle virna ülaossa ning seejärel sundida int 3h generatsiooni. Kui meie töötleja saab kontrolli, siis protsessi ei silu – vastasel juhul saame siluri tuvastamisel sundida silumisvastaseid meetmeid.

Järeldus

Need on vaid mõned silumisvastased tehnikad nende suurest hulgast.

Hea tava on kombineerida erinevaid tagurdamisvastaseid tehnikaid, mis muudab kaitsest möödahiilimise palju raskemaks. Täiendavad kontrollid võivad rakenduse täitmist aeglustada, mistõttu rakendatakse patenteeritud tehnoloogiaid ja oskusteavet sisaldavatele põhimoodulitele enamasti tugevaimaid kaitsetehnikaid. Lõpuks on see kompromiss koodi ohutuse taseme ja rakenduse jõudluse vahel.

Tahaksin mainida, et tarkvara pöördprojekteerimine ei ole alati ebaseaduslik ja mõnikord saab seda uurimisprotsessi käigus rakendada selliste ülesannete jaoks nagu ühilduvuse parandamine, paikamine, dokumenteerimata süsteemiliidese kasutamine jne. Juriidilised pöördprojekteerimise teenused professionaalide tarnitud tegelevad ka silumisvastase kaitsega, kuid teisest küljest – sellest möödaminnes.