Viimase kahe nädala jooksul oleme näinud mitmeid artikleid, mis räägivad populaarses avatud lähtekoodiga paroolihalduris KeePass "peamisest paroolimurdmisest".
Viga peeti piisavalt oluliseks, et saada USA valitsuse ametlik tunnus (seda nimetatakse CVE-2023-32784, kui soovite seda jahtida) ja arvestades, et teie paroolihalduri põhiparool on peaaegu kogu teie digitaalse lossi võti, saate aru, miks lugu palju elevust tekitas.
Hea uudis on see, et ründaja, kes soovis seda viga ära kasutada, peab peaaegu kindlasti olema teie arvuti juba pahavaraga nakatanud ja saaks seetõttu igal juhul teie klahvivajutuste ja töötavate programmide järele luurata.
Teisisõnu võib viga pidada kergesti juhitavaks riskiks, kuni KeePassi looja tuleb välja värskendusega, mis peaks varsti (ilmselt 2023. aasta juuni alguses) ilmuma.
Nagu vea avalikustaja hoolitseb välja tooma:
Kui kasutate tugeva parooliga ketta täielikku krüptimist ja teie süsteem on [pahavaravaba], peaks kõik korras olema. Ainult selle leidmisega ei saa keegi teie paroole Interneti kaudu eemalt varastada.
Riskid selgitatud
Kokkuvõtteks võib öelda, et viga taandub raskustele tagada, et kõik konfidentsiaalsete andmete jäljed kustutatakse mälust, kui olete nendega lõpetanud.
Jätame siinkohal tähelepanuta probleemid, kuidas vältida salajaste andmete kogumist mällu, kasvõi lühidalt.
Selles artiklis tahame lihtsalt programmeerijatele kõikjal meelde tuletada, et turvateadlik ülevaataja on heaks kiitnud koodi kommentaariga, näiteks "näib, et see puhastab enda järelt õigesti" ...
… ei pruugi tegelikult täielikult puhastada ja võimalik andmete leke ei pruugi olla ilmne koodi enda otsesel uurimisel.
Lihtsamalt öeldes tähendab haavatavus CVE-2023-32784, et KeePassi põhiparool võib olla süsteemiandmetest taastatav isegi pärast KeyPassi programmi väljumist, kuna teie parooli kohta on piisavalt teavet (kuigi mitte algparooli enda kohta, millele keskendume hetkega sisse lülitada) võib süsteemi vahetus- või puhkefailides maha jääda, kus eraldatud süsteemimälu võidakse hiljem salvestada.
Windowsi arvutis, kus BitLockerit ei kasutata kõvaketta krüptimiseks, kui süsteem on välja lülitatud, annaks see kelm, kes varastas teie sülearvuti, võimaluse USB- või CD-seadmest käivitada ja isegi teie peaparooli taastada. kuigi programm KeyPass ise hoolitseb selle eest, et seda kunagi jäädavalt kettale ei salvestataks.
Pikaajaline paroolileke mällu tähendab ka seda, et parooli saab teoreetiliselt taastada KeyPassi programmi mälutõmmistest, isegi kui see väljavõte võeti kinni kaua pärast parooli sisestamist ja kaua pärast KeePassi. endal polnud enam vajadust seda endal hoida.
Ilmselgelt peaksite eeldama, et teie süsteemis juba olev pahavara suudab erinevate reaalajas nuhkimistehnikate abil taastada peaaegu kõik sisestatud paroolid, kui need olid tippimise ajal aktiivsed. Kuid võite põhjendatult eeldada, et teie ohule allutatud aeg piirdub lühikese tippimisperioodiga, mitte pikemaks minutiks, tunniks või päevaks pärast seda või võib-olla kauemgi, sealhulgas pärast arvuti väljalülitamist.
Mis jääb maha?
Seetõttu mõtlesime, et vaatame kõrgel tasemel, kuidas salajased andmed võivad mällu jääda viisil, mis koodist otseselt välja ei paista.
Ärge muretsege, kui te ei ole programmeerija – teeme asja lihtsaks ja selgitame edasi.
Alustuseks vaatame mälukasutust ja -puhastust lihtsas C-programmis, mis simuleerib parooli sisestamist ja ajutist salvestamist, tehes järgmist.
- Spetsiaalse mälumahu eraldamine spetsiaalselt parooli salvestamiseks.
- Tuntud tekstistringi sisestamine et saaksime selle vajaduse korral mälust hõlpsasti üles leida.
- 16 pseudojuhusliku 8-bitise ASCII tähemärgi lisamine vahemikust AP.
- Välja trükkimine simuleeritud paroolipuhver.
- Mälu vabastamine lootuses kustutada paroolipuhver.
- Väljudes programm.
Oluliselt lihtsustatult võib C-kood välja näha umbes selline, ilma veakontrollita, kasutades C-käitusfunktsiooni halva kvaliteediga pseudojuhuslikke numbreid rand()
, ja ignoreerides puhvri ületäitumise kontrolle (ärge kunagi tehke seda päriskoodis!):
// Ask for memory char* buff = malloc(128); // Copy in fixed string we can recognise in RAM strcpy(buff,"unlikelytext"); // Append 16 pseudo-random ASCII characters for (int i = 1; i <= 16; i++) { // Choose a letter from A (65+0) to P (65+15) char ch = 65 + (rand() & 15); // Modify the buff string directly in memory strncat(buff,&ch,1); } // Print it out, so we're done with buff printf("Full string was: %sn",buff); // Return the unwanted buffer and hope that expunges it free(buff);
Tegelikult sisaldab kood, mida lõpuks oma testides kasutasime, mõningaid täiendavaid bitte ja tükke, mis on näidatud allpool, et saaksime oma ajutise paroolipuhvri kogu sisu välja jätta, et otsida soovimatut või allesjäänud sisu.
Pange tähele, et pärast helistamist kustutame puhvri tahtlikult free()
, mis on tehniliselt kasutus-pärast-vaba viga, kuid teeme seda siin salakaval viisil, et näha, kas pärast puhvri tagasiandmist ei jää midagi kriitilist maha, mis võib päriselus põhjustada ohtliku andmelekke augu.
Sisestasime ka kaks Waiting for [Enter]
viipab koodi, et anda endale võimalus programmi põhipunktides mälupilte luua, andes meile toorandmeid, mida hiljem otsida, et näha, mis programmi töötamise käigus maha jäi.
Mälu tühjendamiseks kasutame Microsofti Sysinternalsi tööriist procdump
koos -ma
valik (tühjendage kogu mälu), mis väldib vajadust kirjutada Windowsi kasutamiseks oma koodi DbgHelp
süsteem ja selle üsna keeruline MiniDumpXxxx()
funktsioonid.
C-koodi koostamiseks kasutasime oma väikest ja lihtsat Fabrice Bellardi tasuta ja avatud lähtekoodiga versiooni Väike C-kompilaator, saadaval 64-bitise Windowsi jaoks allikas ja kahendvorm otse meie GitHubi lehelt.
Kogu artiklis kujutatud lähtekoodi kopeeritav ja kleepitav tekst kuvatakse lehe allosas.
Testprogrammi koostamisel ja käivitamisel juhtus järgmine:
C:UsersduckKEYPASS> petcc64 -stdinc -stdlib unl1.c Pisike C-kompilaator – Autoriõigus (C) 2001-2023 Fabrice Bellard eemaldatud Paul Ducklini poolt õppevahendina kasutamiseks Versioon petcc64-0.9.27 [0006] - Generates 64 Ainult PE-d -> unl1.c -> c:/users/duck/tcc/petccinc/stdio.h [. . . .] -> c:/users/duck/tcc/petcclib/libpetcc1_64.a -> C:/Windows/system32/msvcrt.dll -> C:/Windows/system32/kernel32.dll -------- ----------------------- virt faili suurus jaotis 1000 200 438 .text 2000 800 2ac .data 3000 c00 24 .pdata --------- ----------------------- <- unl1.exe (3584 baiti) C:UsersduckKEYPASS> unl1.exe Uue puhvri kustutamine alguses 00F51390: 90 57 F5 00 00 00 00 00 50 01 F5 00 00 00 00 00 .W......P....... 00F513A0: 73 74 65 6D 33 32 5C 63 6D 64 2E 65 78 . exe.D 65F00B44: 32 00 513 0 72 69 76 65 72 44D 61 74A 61C 3 43 3E jõgiAndmed=C:Win 5F57C69: 6 00F 513 0 64C 6 77 73C 5 53D 79 73 74 dowsSystem65Dr 6F33D32: 5 44 72 32 00 513C 0 69 76 65 72 73 5 44 72 69 ivers DriverData 76F65E72: 44 61 74 61 00F 513 0 00 45 46D 43 5 34F33 37F . F32F3: 31 00 46F 50 53 5 4372 1F 00 513 0 42F 52 4 57F 53 BROWSER_APP_PROF 45F52: 5 41C 50 50F 5 50 52 4 46E 00 51400D 49 4E 45 5 53 ILE_STRING=Inter 54:52E 49F4 47 3C 49A 6 F74 65C AC 72B 00 51410 net ExplzV.< .K.. Täielik string oli: ebatõenäoline tekstJHKNEJJCPOMDJHAN 6F65: 74 20E 45C 78 70B 6 7C 56 4 3 4 00 00A 00 51390B 75E ebatõenäoline tekstJHKN 6F6F69A 6 65A 6 79 74E 65 78 74 4 EJJCPOMDJHAN.eD 48F4B4 - 00Dr 513F0D45: 4 4 43 50 4 4C 44 4 48 41 4 00 65 00 44 00 iversDriverData 513F0E72: 69 76 65 72 44F 61 74 61 3 43D 3 5 57 69 6 00F .513F0 .EFC . 64 6F 77 73 5 53 79F 73 74 65 6F 33 32 5F 44 BROWSER_APP_PROF 72F32: 00 513C 0 69F 76 65 72 73 5E 44 72D 69 76E 65 72 44 ILE_STRING=Inter 61F74: 61E 00A F 513: 0E 00A 45 46 43 5 34 33C AC 37B 32 3 net ExplzV.<.K.. Ootab [ENTER] puhvri vabastamist... Puhvri tühjendamine pärast vaba() 31F00: A46 50 F53 5 4372 1 00 513 0 42 F52 4 57 53 45 52 .g......P...... . 5F41A50: 50 5A 50A 52 4 46F 00D 51400 49A 4 45 5E 53 54 52 49 EJJCPOMDJHAN.eD 4F47B3: 49 6 74 65 72 00 51410 6 65E riverData=C:Win 74F20C45: 78 70F 6 7 56C 4 3 4 00 00 00D 51390 0 67C 5 00 dowsSystem00Dr 00F00D00: 50 01 5 00 00 00C 00 00 00 513 0 45 4 4 43 50 4 4 44F 4 48 41: 4 00 65 00 44F 00 513 0 72 69D 76 65 72 44 61 74F .EFC_61=3.FPS_ 43F3F5: 57 69 6F 00 513 0 64 6F 77 73 5 53F 79 73 74F 65 BROWSER_APP_PROF 6F33C 32 5 44 72 E 32 00D 513 0E 69 76 65 ILE_STRING=Inter 72F73: 5E 44 72 69 76 65 72 44C 61D 74 61 00D AC 513B 0 00 net ExplM..MK. Main()-st väljumiseks [ENTER] ootamine... C:UsersduckKEYPASS>
Sellel jooksul ei viitsinud me mingeid protsessimälu tühjendajaid haarata, sest väljundist oli kohe näha, et see kood lekib andmeid.
Kohe pärast Windows C käitusaja teegi funktsiooni kutsumist malloc()
, näeme, et puhver, mille me tagasi saame, sisaldab keskkonnamuutujate andmeid, mis on programmi käivituskoodist alles jäänud, kusjuures esimesed 16 baiti on ilmselt muudetud nii, et need näevad välja nagu mingi allesjäänud mälujaotuse päis.
(Pange tähele, kuidas need 16 baiti näevad välja nagu kaks 8-baidist mäluaadressi, 0xF55790
ja 0xF50150
, mis on vastavalt vahetult pärast ja vahetult enne meie enda mälupuhvrit.)
Kui parool peaks olema mälus, näeme kogu stringi puhvris selgelt, nagu me eeldamegi.
Aga peale helistamist free()
, pange tähele, kuidas meie puhvri esimesed 16 baiti on uuesti ümber kirjutatud lähedal asuvate mäluaadressidega, arvatavasti nii, et mälujaotur saaks jälgida mälus olevaid plokke, mida ta saab uuesti kasutada...
… aga ülejäänud meie "kustutatud" paroolitekst (viimased 12 juhuslikku tähemärki EJJCPOMDJHAN
) on maha jäänud.
Lisaks sellele, et me peame haldama C-s oma mälueraldisi ja eraldamisi, peame ka tagama, et valime andmepuhvrite jaoks õiged süsteemifunktsioonid, kui tahame neid täpselt juhtida.
Näiteks sellele koodile lülitudes saame mälus oleva üle veidi suurema kontrolli:
Vahetades malloc()
ja free()
madalama taseme Windowsi jaotamisfunktsioonide kasutamiseks VirtualAlloc()
ja VirtualFree()
otse, saame parema kontrolli.
Kuid me maksame hinda kiirus, sest iga kõne VirtualAlloc()
teeb rohkem tööd kui helistada malloc()
, mis töötab pidevalt jagades ja jagades eelnevalt eraldatud madala taseme mälu plokki.
Kasutamine VirtualAlloc()
Korduvalt väikeste plokkide puhul kulutab ka üldiselt rohkem mälu, sest iga plokk kulub ära VirtualAlloc()
tarbib tavaliselt 4KB-kordset mälu (või 2MB, kui kasutate nn suured mälulehed), nii et meie ülaltoodud 128-baidine puhver ümardatakse üles 4096 baiti, raiskades 3968KB mäluploki lõpus olevad 4 baiti.
Kuid nagu näete, kustutatakse tagasi saadud mälu automaatselt (nullile seatud), nii et me ei näe, mis seal varem oli, ja seekord jookseb programm kokku, kui proovime kasutada pärast vaba kasutamist. trikk, sest Windows tuvastab, et püüame piiluda mälusse, mis meile enam ei kuulu:
C:UsersduckKEYPASS> unl2 "Uue" puhvri kustutamine alguses 0000000000EA0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000 0010 00 00 00 EA00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000 0020 ................ 00EA00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000 0030 ............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0000000000EA0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0000000000EA0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0000000000EA0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0000000000EA0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Täisstring oli: ebatõenäolinetekstIBIPJPPHEOPOIDLL 00EA00: 00 0000000000E 0080C 00 00B 00 00C 00 00 00 00 00 00 00 00 00 ebatõenäolinetekst IBIPJPPHEOPOIDLL 00IP00 IBIP00 0000000000 0000 75 6F 6 69F 6 65 6C 79C 74 65 78 74 49 JPPHEOPOIDLL .... 42A49: 50 0000000000 0010 4 50 50 48 45 4 50 4 49 44 4 4 00 00 00 00 0000000000 0020 00 00 00 00 00 .................... 00 : 00 00 00 00 00 00 00 00 00 00 0000000000 0030 00 00 00 00 ................ 00EA00: 00 00 00 00 00 00 00 00 00 00 0000000000 0040 00 00 00 00 ................ 00EA00: 00 00 00 00 00 00 00 00 00 00 0000000000 0050 00 00 00 00 ............... . 00EA00: 00 00 00 00 00 00 00 00 00 00 0000000000 0060 00 00 00 00 ................ 00EA00: 00 00 00 00 00 00 00 00 00 00 0000000000 0070 ................ 00EA00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000 0080 ............. ... Ootan, kuni [ENTER] puhvri vabastab... Puhvri tühjendamine pärast free() 00EA00: [Programm lõpetati siin, kuna Windows tabas meie kasutus-pärast-vabadust]
Kuna vabastatud mälu tuleb uuesti eraldada VirtualAlloc()
enne kui seda saab uuesti kasutada, võime eeldada, et see nullitakse enne ringlussevõttu.
Kui aga tahame veenduda, et see oleks kustutatud, võiksime kutsuda Windowsi erifunktsiooni RtlSecureZeroMemory()
vahetult enne selle vabastamist, tagamaks, et Windows kirjutab esmalt meie puhvrisse nullid.
Seotud funktsioon RtlZeroMemory()
, kui huvitab, teeb sarnast asja, kuid ilma tegeliku töötamise garantiita, sest kompilaatoritel on lubatud see teoreetiliselt üleliigse eemaldada, kui nad märkavad, et pärast seda puhvrit enam ei kasutata.
Nagu näete, peame õigete Windowsi funktsioonide kasutamise eest hoolt kandma, kui tahame minimeerida aega, mille jooksul mällu salvestatud saladused võivad hilisemaks jääda.
Selles artiklis me ei uuri, kuidas vältida saladuste kogemata salvestamist teie vahetusfaili, lukustades need füüsilisse RAM-i. (Vihje: VirtualLock()
ei ole tegelikult piisav.) Kui soovite rohkem teada saada madala taseme Windowsi mäluturbe kohta, andke meile sellest kommentaarides teada ja me vaatame seda tulevases artiklis.
Automaatse mäluhalduse kasutamine
Üks hea viis, kuidas vältida mälu iseseisvat eraldamist, haldamist ja eraldamist, on kasutada programmeerimiskeelt, mis hoolitseb malloc()
ja free()
või VirtualAlloc()
ja VirtualFree()
, automaatselt.
Skriptikeel nagu Perl, Python, Kuu, JavaScript ja teised vabanevad kõige levinumatest mälu turvavigadest, mis kimbutavad C- ja C++-koodi, jälgides teie mälukasutust taustal.
Nagu me varem mainisime, töötab meie ülaltoodud halvasti kirjutatud C-näidis praegu hästi, kuid ainult seetõttu, et see on endiselt ülilihtne programm fikseeritud suurusega andmestruktuuridega, kus saame kontrollimise teel kontrollida, et me oma 128-koodi üle ei kirjuta. baidipuhver ja et on ainult üks täitmistee, mis algab malloc()
ja lõpeb vastavaga free()
.
Kui aga värskendaksime seda, et võimaldada muutuva pikkusega paroolide genereerimist, või lisaksime genereerimisprotsessi lisafunktsioone, võib meil (või kes iganes, kes järgmisena koodi haldab) tekkida kergesti puhvri ületäitumine, pärast tasuta kasutusviga või mälu, mis ei vabane kunagi ja jätab seetõttu salajased andmed veel kauaks rippuma ka pärast seda, kui neid enam vaja pole.
Sellises keeles nagu Lua saame lubada Lua käitusaegsel keskkonnal, mis teeb seda, mida žargoonis nimetatakse automaatne prügivedu, tegeleb süsteemist mälu hankimisega ja selle tagastamisega, kui tuvastab, et oleme selle kasutamise lõpetanud.
Eespool loetletud C-programm muutub palju lihtsamaks, kui mälu eraldamise ja eraldamise eest hoolitseme meie eest:
Jaotame mälu stringi hoidmiseks s
lihtsalt stringi määramisega 'unlikelytext'
seda.
Võime hiljem Luale selgesõnaliselt vihjata, et me ei ole enam huvitatud s
määrates sellele väärtuse nil
(kõik nils
on sisuliselt sama Lua objekt) või lõpetage kasutamine s
ja oodake, kuni Lua tuvastab, et seda pole enam vaja.
Mõlemal juhul kasutatud mälu s
taastatakse lõpuks automaatselt.
Ja vältimaks puhvri ületäitumist või suuruse valesti haldamist tekstistringidele lisamisel (Lua operaator ..
, hääldatakse segadus, sisuliselt lisab kaks stringi kokku, nagu +
Pythonis), iga kord, kui me stringi pikendame või lühendame, eraldab Lua võluväel ruumi täiesti uuele stringile, mitte ei muudaks või asendaks algset olemasolevas mälukohas.
See lähenemine on aeglasem ja toob kaasa mälukasutuse piigid, mis on tekstiga töötlemise ajal eraldatud vahestringide tõttu kõrgemad kui C-s, kuid puhvri ületäitumise korral on see palju turvalisem.
Kuid selline automaatne stringihaldus (žargoonis tuntud kui muutmatus, sest stringid ei saa kunagi muteerunud, või paigas muudetud, kui need on loodud), toob küberjulgeolekuga seotud peavalud omaette.
Käitasime ülaltoodud Lua programmi Windowsis kuni teise pausini vahetult enne programmi väljumist:
C:UsersduckKEYPASS> lua s1.lua Täisstring on: ebatõenäolinetekstHLKONBOJILAGLNLN Enne stringi vabastamist ootan [ENTER]... Enne väljumist ootan [ENTER]...
Seekord tegime protsessimälu tõmmise, näiteks järgmiselt:
C:UsersduckKEYPASS> procdump -ma lua lua-s1.dmp ProcDump v11.0 – Sysinternalsi protsessitõmmise utiliit Autoriõigus (C) 2009-2022 Mark Russinovich ja Andrew Richards Sysinternals – www.sysinternals.com [00:00:00] Dump algatatud: C:UsersduckKEYPASSlua-s1.dmp [1:00:00] 00. tühjendus: hinnanguline tühjefaili suurus on 1 MB. [10:00:00] Väljatõmme 00 valmis: 1 MB kirjutatud 10 sekundiga [0.1:00:00] Väljatõmmete arv on saavutatud.
Seejärel käivitasime selle lihtsa skripti, mis loeb tõmmisfaili tagasi ja leiab kõikjal mälust, et see teadaolev string unlikelytext
ilmus ja prindib selle välja koos selle asukohaga dumpfailis ja kohe järgnenud ASCII-märkidega:
Isegi kui olete varem skriptikeeli kasutanud või töötanud mis tahes programmeerimisökosüsteemis, mis sisaldab nö hallatud stringid, kus süsteem jälgib teie jaoks mälu eraldamist ja eraldamist ning käsitleb neid vastavalt oma äranägemisele…
... võite olla üllatunud, kui näete selle mälu skannimise väljundit:
C:UsersduckKEYPASS> lua findit.lua lua-s1.dmp 006D8AFC: ebatõenäoline tekstALJBNGOAPLLBDEB 006D8B3C: ebatõenäoline tekstALJBNGOA 006D8B7C: ebatõenäoline tekstALJBNGO 006D8B006C: ebatõenäoline tekstALJBNGO 8D006AFC: ebatõenäoline tekst ALJBNGO 8D7AFC:006D903AFC006BDCN90LLBFC006: lytextALJBN 90D006D913C: ebatõenäoline tekstALJBNGOAP 006D91C: ebatõenäoline tekstALJBNGOAPL 006D91BC: ebatõenäoline tekstALJBNGOAPLL 006D923FC: ebatõenäoline tekstALJBNG 006D70BALCBALBALJBNG 006D8BBALBALJBlike006tekst0 XNUMXDXNUMXFC: ebatõenäoline tekstALJBNGOAPLLBD XNUMXDXNUMXC : ebatõenäoline tekstALJBNGOAPLLBDE XNUMXDBXNUMXC: ebatõenäoline tekstALJ XNUMXDBBXNUMXC: ebatõenäoline tekstAL XNUMXDBDXNUMXC: ebatõenäoline tekstA
Vaata ja ennäe, sel ajal, kui me oma mäluprügist kinni haarasime, kuigi olime nööriga lõpetanud s
(ja ütles Luale, et meil pole seda enam vaja, öeldes s = nil
), olid kõik koodiga loodud stringid endiselt RAM-is olemas, neid polnud veel taastatud ega kustutatud.
Tõepoolest, kui sorteerime ülaltoodud väljundi stringide endi järgi, selle asemel, et järgida järjekorda, milles need RAM-is ilmusid, saate kujutada, mis juhtus tsükli ajal, kus ühendasime oma paroolistringiga ühe märgi korraga:
C:UsersduckKEYPASS> lua findit.lua lua-s1.dmp | sorteeri /+10 006DBD0C: ebatõenäolinetekstA 006DBB8C: ebatõenäolinetekstAL 006DB70C: ebatõenäolinetekstALJ 006D91BC: ebatõenäolinetekstALJB 006D8CBC: ebatõenäolinetekstALJBN 006D90FC: ebatõenäolinetekstALJB006BBJ8tekstALJB7BBD006:8NB3 006B8C: ebatõenäoline tekstALJBNGOA 7D006D903C: ebatõenäolinetekstALJBNGOAP 006D90C: ebatõenäoline tekstALJBNGOAPL 006D913BC: ebatõenäoline tekstALJBNGOAPLL 006D91C: ebatõenäoline tekstAP ALJBNGONB006 unlike D923C: ebatõenäoline tekstALJBNGOAPLLBDE 006D8AFC: ebatõenäoline tekstALJBNGOAPLLBDEB 006D8BFC : ebatõenäoline tekstALJBNGOAPLLBDEBJ
Kõik need ajutised, vahepealsed stringid on endiselt alles, nii et isegi kui oleksime lõpliku väärtuse edukalt kustutanud s
, lekitaksime ikkagi kõike peale selle viimase tegelase.
Tegelikult isegi siis, kui me sundisime oma programmi sihilikult eemaldama kõik mittevajalikud andmed, kutsudes välja spetsiaalse Lua funktsiooni. collectgarbage()
(enamikul skriptikeeltel on midagi sarnast), jäi enamik nendes tüütavates ajutistes stringides olevatest andmetest niikuinii RAM-i kinni, sest kompileerisime Lua automaatseks mäluhalduseks, kasutades vana head malloc()
ja free()
.
Teisisõnu, isegi pärast seda, kui Lua ise oma ajutised mäluplokid tagasi võttis, et neid uuesti kasutada, ei saanud me kontrollida, kuidas või millal neid mäluplokke uuesti kasutatakse ja seega ka seda, kui kaua nad oma vasakpoolsete mäluplokkidega protsessi sees lebavad. andmete üle, mis ootavad välja nuusutamist, väljaviskamist või muul viisil lekkimist.
Sisestage .NET
Aga kuidas on lood KeePassiga, millest see artikkel alguse sai?
KeePass on kirjutatud C#-s ja kasutab .NET-i käitusaega, nii et see väldib C-programmidega kaasnevaid mäluhäireid...
…aga C# haldab oma tekstistringe, pigem nagu Lua, mis tõstatab küsimuse:
Isegi kui programmeerija väldiks pärast selle lõpetamist kogu peaparooli ühte kohta salvestamist, võivad mäluväljavõttele juurdepääsu omavad ründajad siiski leida piisavalt ajutisi andmeid, et peaparool niikuinii ära arvata või taastada, isegi kui need ründajad said juurdepääsu teie arvutile minutite, tundide või päevade jooksul pärast parooli sisestamist?
Lihtsamalt öeldes, kas teie peaparoolis on tuvastatavaid kummituslikke jäänuseid, mis säilivad RAM-is isegi pärast seda, kui eeldate, et need on kustutatud?
Ärritavalt Githubi kasutajana Vdohney avastas, on vastus (vähemalt 2.54-st varasemate KeePassi versioonide puhul) "Jah."
Selguse huvides ei usu me, et teie tegelikku põhiparooli saab KeePassi mälutõmmisest ühe tekstistringina taastada, kuna autor lõi peaparooli sisestamiseks spetsiaalse funktsiooni, mis ei võimalda kogu parooli salvestamist. parool, kus seda oleks lihtne märgata ja välja nuusutada.
Jäime sellega rahule, määrates oma põhiparooli väärtusele SIXTEENPASSCHARS
, kirjutades selle sisse ja tehes siis kohe, peagi ja kaua pärast seda mäluväljavõtteid.
Otsisime prügimägesid lihtsa Lua skriptiga, mis otsis kõikjalt seda parooliteksti, nii 8-bitises ASCII-vormingus kui ka 16-bitises UTF-16 (Windows Widechar) vormingus, näiteks järgmiselt:
Tulemused olid julgustavad:
C:UsersduckKEYPASS> lua searchknown.lua kp2-post.dmp Dump faili lugemine... VALMIS. SIXTEENPASSCHARSi otsimine 8-bitise ASCII-na... ei leitud. SIXTEENPASSCHARSi otsimine UTF-16-na... ei leitud.
Kuid CVE-2023-32784 avastaja Vdohney märkas, et peaparooli sisestamisel annab KeePass teile visuaalset tagasisidet, koostades ja kuvades kohatäite stringi, mis koosneb Unicode'i blob-märkidest kuni teie parooli pikkuseni (kaasa arvatud). parool:
Windowsi laitekstistringides (mis koosnevad kahest baidist märgi kohta, mitte ainult ühest baidist nagu ASCII-s) kodeeritakse blob-märk RAM-i kuueteistkümnendbaidina. 0xCF
järgnevad 0x25
(mis on ASCII-s lihtsalt protsendimärk).
Seega, isegi kui KeePass hoolitseb parooli sisestamisel sisestatavate töötlemata märkide eest väga ettevaatlikult, võib teil tekkida blob-tähemärkide stringe, mis on korduvate käitamiste käigus hõlpsasti mälus tuvastatavad, näiteks CF25CF25
or CF25CF25CF25
...
…ja kui nii, siis pikim leitud blob-sümbolite hulk jätaks tõenäoliselt teie parooli pikkuse, mis oleks parooliteabe tagasihoidlik vorm, kui mitte midagi muud.
Kasutasime järelejäänud parooli kohatäite stringide märkide otsimiseks järgmist Lua skripti:
Väljund oli üllatav (oleme ruumi säästmiseks kustutanud järjestikused read, millel on sama arv plekid või vähem plekid kui eelmisel real):
C:UsersduckKEYPASS> lua findblobs.lua kp2-post.dmp 000EFF3C: * [. . .] 00BE621B: ** 00BE64C7: *** [. . .] 00BE6E8F: **** [. . .] 00BE795F: ***** [. . .] 00BE84F7: ****** [. . .] 00BE8F37: ******* [ jätkab samamoodi 8 blob, 9 blob jne puhul ] [ kuni kahe viimase reani, millest igaüks koosneb täpselt 16 blobist ] 00C0503B: ************* *** 00C05077: **************** 00C09337: * 00C09738: * [ kõik ülejäänud vasted on ühe täpi pikkused] 0123B058: *
Lähedaste, kuid pidevalt suurenevate mäluaadresside juures leidsime süstemaatilise loendi 3 blobist, seejärel 4 blobist ja nii edasi kuni 16 blobini (meie parooli pikkus), millele järgnesid paljud juhuslikult hajutatud üksikute blob-stringide eksemplarid. .
Tundub, et need kohatäite “blob” stringid lekivad mällu ja jäävad parooli pikkuse lekitamiseks maha kaua pärast seda, kui KeePassi tarkvara on lõpetanud teie peaparooli.
Järgmine samm
Otsustasime edasi kaevata, täpselt nagu Vdohney tegi.
Muutsime oma mustri sobitamise koodi, et tuvastada blob-märkide ahelaid, millele järgneb üks ASCII-märk 16-bitises vormingus (ASCII-märgid on UTF-16-s esitatud tavalise 8-bitise ASCII-koodina, millele järgneb nullbait).
Seekord oleme ruumi säästmiseks maha surunud väljundi kõigi vastete jaoks, mis täpselt vastavad eelmisele:
Üllatus, üllatus:
C:UsersduckKEYPASS> lua searchkp.lua kp2-post.dmp 00BE581B: *I 00BE621B: **X 00BE6BD3: ***T 00BE769B: ****E 00BE822B: *****E 00BE8C6B: ******N 00BE974B: *******P 00BEA25B: ********A 00BEAD33: *********S 00BEB81B: **********S 00BEC383: ***********C 00BECEEB: ************H 00BEDA5B: *************A 00BEE623: **************R 00BEF1A3: ***************S 03E97CF2: *N 0AA6F0AF: *W 0D8AF7C8: *X 0F27BAF8: *S
Vaadake, mida me .NET-i hallatavast stringimälu piirkonnast saame!
Tihedalt koondatud ajutiste "blob stringide" komplekt, mis paljastab meie parooli järjestikused märgid, alustades teisest märgist.
Nendele lekkivatele stringidele järgnevad laialt levinud ühetähemärgilised vasted, mis meie arvates tekkisid juhuslikult. (KeePassi tühjendusfail on umbes 250 MB suurune, nii et "blob" tähemärkidel on piisavalt ruumi, et ilmuda justkui õnne pärast.)
Isegi kui võtame need neli täiendavat vastet arvesse, selle asemel, et neid tõenäoliste mittevastavustena kõrvale jätta, võime arvata, et põhiparool on üks järgmistest:
?IXTEENPASSCHARS ?NXTEENPASSCHARS ?WXTEENPASSCHARS ?SXTEENPASSCHARS
Ilmselgelt ei leia see lihtne tehnika paroolist esimest tähemärki, sest esimene “blob string” konstrueeritakse alles pärast selle esimese märgi sisestamist
Pange tähele, et see loend on kena ja lühike, kuna filtreerisime välja vasted, mis ei lõppenud ASCII-märkidega.
Kui otsisite erinevas vahemikus olevaid tähemärke, näiteks hiina või korea tähemärke, võite saada rohkem juhuslikke tabamusi, sest on palju rohkem võimalikke märke, millega sobitada…
...aga me kahtlustame, et jõuate niikuinii oma peaparoolile üsna lähedale ja parooliga seotud "blob-stringid" näivad olevat RAM-is rühmitatud, arvatavasti seetõttu, et need eraldas umbes samal ajal sama osa paroolist. .NET käitusaeg.
Ja seal on pikas ja diskursiivses pähklikoores selle põnev lugu CVE-2023-32784.
Mida teha?
- Kui olete KeePassi kasutaja, ärge sattuge paanikasse. Kuigi see on viga ja tehniliselt ärakasutatav haavatavus, peavad kaugründajad, kes soovivad selle vea abil teie parooli murda, esmalt teie arvutisse pahavara implanteerima. See annaks neile palju muid võimalusi teie paroolide otse varastamiseks, isegi kui seda viga ei eksisteeriks, näiteks logides teie klahvivajutused tippimise ajal sisse. Siinkohal võite lihtsalt oodata eelseisvat värskendust ja haarata selle kätte, kui see on valmis.
- Kui te ei kasuta täisketta krüptimist, kaaluge selle lubamist. Ülejäänud paroolide eraldamiseks teie vahetusfailist või talveunerežiimi failist (operatsioonisüsteemi kettafailid, mida kasutatakse mälu sisu ajutiseks salvestamiseks suure koormuse ajal või kui teie arvuti on "uinunud"), vajavad ründajad otsest juurdepääsu teie kõvakettale. Kui teil on muude operatsioonisüsteemide jaoks aktiveeritud BitLocker või selle ekvivalent, ei pääse nad juurde teie vahetusfailile, talveunerežiimi failile ega muudele isiklikele andmetele, nagu dokumendid, arvutustabelid, salvestatud meilid jne.
- Kui olete programmeerija, hoidke end mäluhalduse probleemidega kursis. Ärge arvake, et ainult sellepärast, et iga
free()
vastab sellele vastavalemalloc()
et teie andmed on turvalised ja hästi hallatud. Mõnikord peate võib-olla võtma täiendavaid ettevaatusabinõusid, et vältida salajaste andmete lebama jätmist, ja need ettevaatusabinõud operatsioonisüsteemist operatsioonisüsteemini. - Kui olete kvaliteedikontrolli testija või koodi ülevaataja, mõelge alati kulisside taha. Isegi kui mäluhalduskood näib korras ja hästi tasakaalustatud, olge kursis kulisside taga toimuvaga (sest algne programmeerija ei pruukinud seda teha) ja valmistuge tegema eeltestimise stiilis töid, nagu käitusaja jälgimine ja mälu. dumping, et kontrollida, kas turvaline kood tõesti käitub nii, nagu peab.
ARTIKLI KOOD: UNL1.C
#kaasa #kaasa #kaasa void hexdump(unsigned char* buff, int len) { // Trüki puhver 16-baidiste tükkidena jaoks (int i = 0; i < len+16; i = i+16) { printf("%016X: ",buff +i); // Kuva 16 baiti kuueteistkümnendväärtustena jaoks (int j = 0; j < 16; j = j+1) { printf("%02X ",buff[i+j]); } // Korrake neid 16 baiti märkidena (int j = 0; j < 16; j = j+1) { unsigned ch = buff[i+j]; printf("%c",(ch>=32 && ch<=127)?ch:'.'); } printf("n"); } printf("n"); } int main(void) { // Parooli salvestamiseks mälu hankimine ja puhvri // sisu näitamine, kui see on ametlikult "uus"... char* buff = malloc(128); printf("Uue puhvri kustutamine alguses"); hexdump(buff,128); // Kasuta pseudojuhuslikku puhvri aadressi juhusliku seemnena srand((unsigned)buff); // Parooli käivitamine fikseeritud otsitava tekstiga strcpy(buff"unlikelytext"); // Lisage 16 pseudojuhuslikku tähte, ükshaaval (int i = 1; i <= 16; i++) { // Valige täht vahemikust A (65+0) kuni P (65+15) char ch = 65 + (rand() & 15); // Seejärel muutke buff stringi kohas strncat(buff,&ch,1); } // Täisparool on nüüd mälus, seega printi // see stringina ja näita kogu puhvrit... printf("Täisstring oli: %sn",buff); hexdump(buff,128); // Peatage protsessi RAM-i tühjendamiseks kohe (proovige: 'procdump -ma') puts("Ootab [ENTER] puhvri vabastamist..."); getchar(); // Vabastage mälu formaalselt () ja näidake uuesti puhvrit //, et näha, kas midagi on maha jäänud... free(buff); printf("Dumpingu puhver pärast free()n"); hexdump(buff,128); // Pause RAM-i tühjendamiseks uuesti erinevuste kontrollimiseks puts("Ootab [ENTER]-st väljumist main()..."); getchar(); tagasi 0; }
ARTIKLI KOOD: UNL2.C
#kaasa #kaasa #kaasa #kaasa void hexdump(unsigned char* buff, int len) { // Trüki puhver 16-baidiste tükkidena jaoks (int i = 0; i < len+16; i = i+16) { printf("%016X: ",buff +i); // Kuva 16 baiti kuueteistkümnendväärtustena jaoks (int j = 0; j < 16; j = j+1) { printf("%02X ",buff[i+j]); } // Korrake neid 16 baiti märkidena (int j = 0; j < 16; j = j+1) { unsigned ch = buff[i+j]; printf("%c",(ch>=32 && ch<=127)?ch:'.'); } printf("n"); } printf("n"); } int main(void) { // Parooli salvestamiseks mälu hankimine ja puhvri // sisu näitamine, kui see on ametlikult "uus"... char* buff = VirtualAlloc(0,128,MEM_COMMIT,PAGE_READWRITE); printf("Uue puhvri kustutamine alguses"); hexdump(buff,128); // Kasuta pseudojuhuslikku puhvri aadressi juhusliku seemnena srand((unsigned)buff); // Parooli käivitamine fikseeritud otsitava tekstiga strcpy(buff"unlikelytext"); // Lisage 16 pseudojuhuslikku tähte, ükshaaval (int i = 1; i <= 16; i++) { // Valige täht vahemikust A (65+0) kuni P (65+15) char ch = 65 + (rand() & 15); // Seejärel muutke buff stringi kohas strncat(buff,&ch,1); } // Täisparool on nüüd mälus, seega printi // see stringina ja näita kogu puhvrit... printf("Täisstring oli: %sn",buff); hexdump(buff,128); // Peatage protsessi RAM-i tühjendamiseks kohe (proovige: 'procdump -ma') puts("Ootab [ENTER] puhvri vabastamist..."); getchar(); // Vabastage formaalselt () mälu ja näidake uuesti puhvrit //, et näha, kas midagi on maha jäänud... VirtualFree(buff,0,MEM_RELEASE); printf("Dumpingu puhver pärast free()n"); hexdump(buff,128); // Pause RAM-i tühjendamiseks uuesti erinevuste kontrollimiseks puts("Ootab [ENTER]-st väljumist main()..."); getchar(); tagasi 0; }
ARTIKLI KOOD: S1.LUA
-- Alustage mõne fikseeritud otsitava tekstiga s = 'ebatõenäoline tekst' -- Lisage 16 juhuslikku tähemärki A-st P-sse, kui i = 1,16 do s = s .. string.char(65+math.random( 0,15)) end print('Täis string on:',s,'n') -- Peata protsessi tühjendamiseks RAM print('Ootab [ENTER] enne stringi vabastamist...') io.read() - - Pühkige string ja märkige muutuja unused s = nil -- tühjendage RAM uuesti, et otsida erinevusi print('Ootan [ENTER] enne väljumist...') io.read()
ARTIKLI KOOD: FINDIT.LUA
-- loe dump failis local f = io.open(arg[1],'rb'):read('*a') -- otsige markeri teksti, millele järgneb üks -- või mitu juhuslikku ASCII märki local b,e ,m = 0,0,nil, samas kui tõene do – otsige järgmist vastet ja jätke meelde nihe b,e,m = f:find('(ebatõenäoline tekst[AZ]+)',e+1) -- väljuge, kui enam pole sobib kui mitte b siis break end -- raporti asukoht ja string leitud print(string.format('%08X: %s',b,m)) end
ARTIKLI KOOD: SEARCHKNOWN.LUA
io.write('Lugemine tõmmisfailis... ') local f = io.open(arg[1],'rb'):read('*a') io.write('DONE.n') io. write('SIXTEENPASSCHARSi otsimine 8-bitise ASCII-vormingus... ') local p08 = f:find('SIXTEENPASSCHARS') io.write(p08 ja 'FOUND' või 'ei leitud','.n') io.write ('SIXTEENPASSCHARSi otsimine UTF-16-na... ') local p16 = f:find('Sx00Ix00Xx00Tx00Ex00Ex00Nx00Px00'.. 'Ax00Sx00Sx00Cx00Hx00Ax00Rx'00) ja 00 UND io 16'p ei leitud','.n')
ARTIKLI KOOD: FINDBLOBS.LUA
-- loe käsureal määratud dump failis local f = io.open(arg[1],'rb'):read('*a') -- Otsige ühte või mitut parooliplokki, millele järgneb mis tahes mitteblob -- Pange tähele, et blob-märgid (●) kodeerivad Windowsi laia tähemärgiks -- väikese lõpu UTF-16 koodidena, mis väljuvad kuueteistkümnendiku kujul CF 25-na. lokaalne b,e,m = 0,0,nil, samas kui true do -- Soovime ühte või mitut plokki, millele järgneb mis tahes mitte-blob. -- Lihtsustame koodi, otsides selgesõnalist CF25 – millele järgneb mis tahes string, milles on ainult CF või 25 –, nii et leiame nii CF25CFCF või CF2525CF kui ka CF25CF25. -- Filtreerime "valepositiivsed tulemused" hiljem välja, kui neid on. -- Peame x25 asemel kirjutama '%%', sest x25 -- märk (protsendimärk) on Lua spetsiaalne otsingumärk! b,e,m = f:find('(xCF%%[xCF%%]*)',e+1) -- välju, kui enam vasteid pole, kui mitte b, siis katkesta lõpp - CMD.EXE ei saa printida plekid, nii et muudame need tähtedeks. print(string.format('%08X: %s',b,m:gsub('xCF%%','*'))) end
ARTIKLI KOOD: SEARCHKP.LUA
-- loe tõmmisfailis, mis on määratud käsureal local f = io.open(arg[1],'rb'):read('*a') local b,e,m,p = 0,0,nil,nil samas true do -- Nüüd tahame ühte või mitut blobi (CF25), millele järgneb kood -- for A..Z, millele järgneb 0 baiti, et teisendada ACSCII UTF-16-ks b,e,m = f:find(' (xCF%%[xCF%%]*[AZ])x00',e+1) -- väljuge, kui enam vasteid pole, kui mitte b, siis katke lõpp - CMD.EXE ei saa printida plekid, seega teisendame need tähed. -- Ruumi säästmiseks eitame järjestikused vasted, kui m ~= p, siis print(string.format('%08X: %s',b,m:gsub('xCF%%','*'))) p = m lõpp lõpp
- SEO-põhise sisu ja PR-levi. Võimenduge juba täna.
- PlatoAiStream. Web3 andmete luure. Täiustatud teadmised. Juurdepääs siia.
- Tuleviku rahapaja Adryenn Ashley. Juurdepääs siia.
- Ostke ja müüge IPO-eelsete ettevõtete aktsiaid koos PREIPO®-ga. Juurdepääs siia.
- Allikas: https://nakedsecurity.sophos.com/2023/05/31/serious-security-that-keepass-master-password-crack-and-what-we-can-learn-from-it/
- :on
- :on
- :mitte
- : kus
- ][lk
- $ UP
- 1
- 10
- 12
- 15%
- 20
- 200
- 2023
- 24
- 250
- 27
- 31
- 3d
- 49
- 50
- 67
- 70
- 72
- 77
- 8
- 9
- a
- Võimalik
- MEIST
- üle
- absoluutne
- AC
- juurdepääs
- konto
- omandama
- omandamine
- aktiivne
- tegelik
- tegelikult
- lisatud
- Täiendavad lisad
- aadress
- aadressid
- Lisab
- pärast
- pärast
- jälle
- Materjal: BPA ja flataatide vaba plastik
- paigutatud
- eraldab
- eraldamine
- eraldised
- võimaldama
- üksi
- mööda
- juba
- Ka
- muuta
- Kuigi
- alati
- an
- ja
- Andrew
- vastus
- mistahes
- midagi
- midagi kriitilist
- ilmuma
- ilmunud
- lähenemine
- heaks
- OLEME
- ümber
- artikkel
- kaubad
- AS
- At
- autor
- auto
- Automaatne
- automaatselt
- saadaval
- vältima
- vältida
- teadlik
- ära
- tagasi
- tagapõhi
- background-image
- BE
- sest
- muutub
- olnud
- enne
- Algus
- taga
- kaamerate taga
- alla
- Parem
- Natuke
- Blokeerima
- Plokid
- piir
- mõlemad
- põhi
- bränd
- Brand New
- Murdma
- lühidalt
- tooma
- puhver
- puhvri ülevool
- Bug
- vead
- ehitama
- kuid
- by
- C + +
- helistama
- kutsudes
- CAN
- Saab
- mis
- juhul
- püütud
- CD
- keskus
- kindlasti
- ketid
- võimalus
- muutunud
- iseloom
- märki
- kontroll
- Kontroll
- hiina
- Vali
- selge
- selgelt
- lähedal
- kood
- värv
- COM
- tuleb
- tulevad
- kommentaar
- kommentaarid
- ühine
- täitma
- keeruline
- arvuti
- Arvestama
- märkimisväärne
- kaaluda
- Koosneb
- ehitamine
- sisu
- sisu
- jätkuvalt
- pidev
- kontrollida
- muutma
- autoriõigus
- Vastav
- võiks
- cover
- pragu
- looma
- loodud
- looja
- kriitiline
- Küberturvalisus
- OHT
- Ohtlik
- andmed
- andmete leke
- Päeva
- tegelema
- otsustatud
- pühendunud
- kirjeldatud
- DID
- erinevused
- erinev
- Raskus
- DIG
- digitaalne
- otsene
- Otsene juurdepääs
- otse
- Ekraan
- väljapanek
- on
- do
- dokumendid
- ei
- Ei tee
- teeme
- tehtud
- Ära
- alla
- ajam
- kaks
- maha kallama
- ajal
- e
- iga
- Ajalugu
- kergesti
- ökosüsteemi
- kumbki
- teine
- kirju
- võimaldades
- julgustav
- krüpteerimist
- lõpp
- lõppeb
- piisavalt
- tagama
- tagades
- sisene
- Sisse
- Kogu
- kanne
- keskkond
- Samaväärne
- viga
- põhiliselt
- Hinnanguliselt
- jms
- Eeter (ETH)
- Isegi
- lõpuks
- aina suurenev
- Iga
- kõik
- täpselt
- näide
- Välja arvatud
- Erutus
- täitmine
- eksisteerima
- olemasolevate
- Väljapääs
- Väljudes
- ootama
- Selgitama
- Ekspluateeri
- avatud
- laiendama
- lisatasu
- väljavõte
- asjaolu
- vale
- lummav
- FUNKTSIOONID
- tagasiside
- vähem
- võitlemine
- fail
- Faile
- filtreerida
- lõplik
- Lõpuks
- leidma
- leidmine
- leiab
- lõpp
- esimene
- fikseeritud
- Keskenduma
- Järgneb
- Järel
- eest
- vorm
- Vormiliselt
- formaat
- eelseisev
- avastatud
- neli
- tasuta
- Alates
- täis
- täielikult
- funktsioon
- funktsioonid
- edasi
- tulevik
- genereerib
- põlvkond
- saama
- saamine
- GitHub
- Andma
- antud
- annab
- andmine
- Go
- Goes
- läheb
- hea
- Valitsus
- rüütama
- suur
- garantii
- olnud
- Varred
- juhtus
- Juhtub
- juhtub
- Raske
- Olema
- võttes
- peavalu
- raske
- kõrgus
- siin
- HEX
- kõrgetasemeline
- rohkem
- Hits
- hoidma
- Auk
- lootus
- Lahtiolekuajad
- hõljuma
- Kuidas
- Kuidas
- HTTPS
- jaht
- i
- tunnus
- if
- kohe
- oluline
- in
- hõlmab
- Kaasa arvatud
- info
- teavitatakse
- selle asemel
- huvitatud
- Kesktaseme
- Internet
- sisse
- küsimustes
- IT
- ITS
- ise
- erikeel
- juuni
- lihtsalt
- ainult üks
- hoidma
- Võti
- Teadma
- teatud
- korea
- keel
- Keeled
- sülearvuti
- viimane
- pärast
- viima
- Leads
- lekkima
- Lekked
- Õppida
- õppimine
- kõige vähem
- jätmine
- lahkus
- Pikkus
- kiri
- Raamatukogu
- elu
- nagu
- Tõenäoliselt
- piiratud
- joon
- liinid
- nimekiri
- Loetletud
- ll
- koormus
- kohalik
- liising
- metsaraie
- Pikk
- pikaajaline
- enam
- Vaata
- näeb välja
- Vaatasin
- otsin
- välimus
- Partii
- õnn
- jääb
- tegema
- malware
- juhtima
- juhitud
- juhtimine
- juht
- haldab
- Manipuleerimine
- palju
- Varu
- märk
- marker
- meister
- Vastama
- sobitamine
- max laiuse
- mai..
- vahendid
- Mälu
- mainitud
- Microsoft
- võib
- protokoll
- tagasihoidlik
- modifitseeritud
- muutma
- hetk
- järelevalve
- rohkem
- kõige
- palju
- mitmekordne
- puhas
- Vajadus
- vaja
- neto
- mitte kunagi
- Sellegipoolest
- Uus
- uudised
- järgmine
- kena
- ei
- normaalne
- mitte midagi
- Märka..
- nüüd
- number
- numbrid
- objekt
- Ilmne
- of
- maha
- ametlik
- Ametlikult
- tasakaalustama
- Vana
- on
- kunagi
- ONE
- ainult
- avatud lähtekoodiga
- tegutsevad
- operatsioonisüsteemi
- operatsioonisüsteemid
- operaator
- valik
- or
- et
- originaal
- Muu
- teised
- muidu
- meie
- ise
- välja
- väljund
- üle
- üldine
- enda
- lehekülg
- Paanika
- osa
- Parool
- Password Manager
- paroolid
- tee
- Muster
- Paul
- paus
- Maksma
- protsent
- ehk
- periood
- püsivalt
- isiklik
- isiklikud andmed
- füüsiline
- pilt
- tükki
- Koht
- kohatäide
- Katk
- Platon
- Platoni andmete intelligentsus
- PlatoData
- rohke
- Punkt
- võrra
- populaarne
- positsioon
- võimalik
- Postitusi
- potentsiaal
- täpselt
- esitada
- ilus
- vältida
- eelmine
- hind
- trükk
- pildid
- tõenäoliselt
- probleeme
- protsess
- Programm
- Programmeerija
- Programmeerijad
- Programming
- Programmid
- hääldatud
- panema
- Python
- Küsimused ja vastused
- küsimus
- tõstab
- RAM
- juhuslik
- valik
- pigem
- Töötlemata
- algandmed
- RE
- jõudis
- Lugenud
- Lugemine
- valmis
- reaalne
- päris elu
- reaalajas
- tõesti
- ära tundma
- Taastuma
- taastumine
- seotud
- ülejäänud
- meeles pidama
- kauge
- kõrvaldama
- kordama
- korduv
- KORDUVALT
- aru
- esindatud
- suhtes
- vastavalt
- REST
- Tulemused
- tagasipöördumine
- tagasi
- avalduma
- Rid
- õige
- Oht
- riskide
- ruum
- jooks
- jooksmine
- käitusaja jälgimine
- s
- ohutu
- ohutum
- sama
- rahul
- Säästa
- ütlus
- skaneerida
- laiali
- stseenide
- Otsing
- otsimine
- Teine
- sekundit
- Saladus
- Osa
- kindlustama
- turvalisus
- vaata
- seeme
- nägemine
- tundub
- nähtud
- näeb
- Seeria
- tõsine
- komplekt
- kehtestamine
- Lühike
- Varsti
- peaks
- näitama
- näidatud
- kirjutama
- Märgid
- sarnane
- Samamoodi
- lihtne
- lihtsustatud
- lihtsustama
- lihtsalt
- ühekordne
- SUURUS
- uni
- väike
- Alatu
- snooping
- So
- tarkvara
- tahke
- mõned
- midagi
- Varsti
- allikas
- lähtekoodi
- Ruum
- eriline
- spetsiaalselt
- määratletud
- kiirus
- Stars
- algus
- alustatud
- Käivitus
- algab
- käivitamisel
- Veel
- varastas
- Peatus
- peatatud
- salvestada
- ladustatud
- Lugu
- nöör
- tugev
- Uuring
- Edukalt
- selline
- piisav
- peaks
- üllatus
- üllatunud
- üllatav
- ellu jääma
- SVG
- vahetama
- süsteem
- süsteemid
- Võtma
- võtnud
- võtab
- võtmine
- rääkimine
- tehniliselt
- tehnikat
- ajutine
- test
- testid
- kui
- et
- .
- Allikas
- oma
- Neile
- ennast
- SIIS
- teooria
- Seal.
- seetõttu
- nad
- asi
- mõtlema
- see
- need
- kuigi?
- arvasin
- aeg
- Kapslid
- et
- kokku
- võttis
- tööriist
- ülemine
- jälgida
- Jälgimine
- üleminek
- läbipaistev
- tõsi
- püüdma
- Pöördunud
- kaks
- tüüp
- tüüpiliselt
- mõistma
- Unicode
- kuni
- kasutamata
- soovimatu
- Värskendused
- ajakohastatud
- URL
- us
- meie valitsus
- Kasutus
- usb
- kasutama
- kasutusvaba
- Kasutatud
- Kasutaja
- kasutusalad
- kasutamine
- kasulikkus
- väärtus
- Väärtused
- sort
- kontrollima
- versioon
- väga
- kaudu
- haavatavus
- W
- ootama
- ootamine
- tahan
- tagaotsitav
- oli
- Watch
- Tee..
- kuidas
- we
- nädalat
- Hästi
- olid
- M
- millal
- kas
- mis
- kuigi
- WHO
- kes iganes
- kogu
- miks
- will
- võitma
- aknad
- pühkige
- koos
- ilma
- ei tea
- sõnad
- Töö
- töötas
- töö
- töötab
- muretsema
- oleks
- annaks
- kirjutama
- kirjutamine
- kirjalik
- veel
- sa
- Sinu
- ise
- sephyrnet
- null