XXE (XML External Entity) Hyökkäykset

Mitä ovat XXE hyökkäykset?

Helppo
45 min

Odottamattomia ominaisuuksia

Haavoittuvuuksia on läjäpäin eri nimisiä, mutta yleensä ne voidaan jakaa huomattavasti pienempään määrään peruskäsitteitä. Yksi näistä käsitteistä on "odottamattomat ominaisuudet", jolla viitataan haavoittuvuuteen joka johtuu siitä, että kehittäjä käyttää sellaista ohjelmistokomponenttia, työkalua, protokollaa, jne. jonka toiminnallisuutta ei täysin ymmärrä.

Tästä yksi mainio esimerkki on 20.000€ bug bounty jonka GitLab maksoi Hackerone-alustalla heidän markdown-editorista löytyneestä RCE (remote code execution, mielivaltaisen koodin suoritus etänä) -haavoittuvuudesta. Kyseessä oli toiminto heidän markdown-käsittelijässä (KramDown) josta he eivät tieneet, jolla pystyikin tekemään ikävyyksiä syöttämällä tietyn muotoista markdownia sovellukseen. https://hackerone.com/reports/1125425

Paljon yleisempi tämän kategorian haavoittuvuus on kuitenkin XXE, josta opimme tällä kurssilla. XXE on lyhenne sanoista XML External Entity, eli XML-protokollan ulkoinen entiteetti. Kyse on siis osasta XML-protokollaa josta kehittäjät usein eivät ole tietoisia.

Mikä XML?

XML (Extensible Markup language) on tekstipohjainen protokolla jolla voidaan esittää rakenteellista dataa. Jos olet nähnyt HTML-koodia, olet todennäköisesti jo tuttu XML rakenteen kanssa, HTML on nimittäin XML-pohjainen kieli.

XML sisältää pääasiallisesti tageja ja attribuutteja. Tagit näyttävät tältä <TAGIN ALKU>TAGIN SISÄLTÖ</TAGIN LOPPU>. Eli esimerkiksi auto, jonka merkki on "Lada" ja vuosimalli "1955" voitaisiin esittää XML:ssä auto-tagina, jonka sisällä on merkki-tagi jonka arvo on Lada, sekä vuosimalli-tagi jonka arvo on 1955.

<auto>
  <merkki>Lada</merkki>
  <vuosimalli>1955</vuosimalli>
</auto>

Attribuutit taas näyttävät tältä:

<auto merkki="Lada" vuosimalli="1955"/>

Yleensä XML:ssä on molempia sekaisin. Eli rakenne on: tageja, tagejen sisällä tekstiä tai tageja, ja kaikilla tageilla voi olla attribuutteja.

DTD

DTD on lyhenne sanoista Document Type Definition ja sillä voidaan määrittää XML-dokumentin rakenne. Määritys tehdään DOCTYPE-tagilla seuraavanlaisesti.

<!DOCTYPE juurielementti [
    elementit ja entiteetit
]>

Tässä esimerkiksi on tehdy DOCTYPE auto, jossa kerrotaan että:

  • <!DOCTYPE auto: XML-dokumentin juuri (root) on auto-tagi
  • <!ELEMENT auto (merkki, vuosimalli)>: auto-tagin pitää sisältää tagit merkki ja vuosimalli
  • <!ELEMENT merkki (#PCDATA)>: merkki-tagin tyyppi on #PCDATA
  • <!ELEMENT vuosimalli (#PCDATA)>: vuosimalli-tagin tyyppi on #PCDATA
<!DOCTYPE auto
[
  <!ELEMENT auto (merkki, vuosimalli)>
  <!ELEMENT merkki (#PCDATA)>
  <!ELEMENT vuosimalli (#PCDATA)>
]>
<auto>
  <merkki>Lada</merkki>
  <vuosimalli>1955</vuosimalli>
</auto>

PCDATA tarkoittaa tekstiä (parseable character data).

Entiteetit

XML on tekstipohjainen protokolla jossa tietyillä merkeillä on erityismerkitys. Esimerkiksi < merkki avaa uuden tagin. Jos haluaa siis tehdä auton jonka merkki on Volvo<XC60> niin se ei suoraan onnistuisi, koska XML-syntaksi hajoaisi.

<auto>
  <merkki>Volvo<XC60></merkki>
  <vuosimalli>2013</vuosimalli>
</auto>

Tästä syystä tiettyjä merkkejä edustetaan XML-syntaksissa entiteetteinä, jos ei halua että merkit muodostuu osaksi XML:n rakennetta. Esimerkiksi < merkki voidaan ilmaista entiteettinä &lt; ja > merkki entiteettinä &gt;.

<auto>
  <merkki>Volvo&lt;XC60&gt;</merkki>
  <vuosimalli>2013</vuosimalli>
</auto>

DTD Entiteetit

Entiteettejä voi määrittää myös itse. Voit esimerkiksi määrittää että siinä missä &gt; entiteetti tarkoittaa >-merkkiä, entiteetti &lempimerkki; tarkoittaa arvoa Volvo. Tämä voidaan tehdä DTD-määrityksessä seuraavanlaisesti:

<!DOCTYPE auto
[
  <!ENTITY lempimerkki "Volvo">
]>
<auto>
  <merkki>&lempimerkki;</merkki>
  <vuosimalli>1955</vuosimalli>
</auto>

Tällöin XML-käsittelijä tulostaisi:

<auto>
  <merkki>Volvo</merkki>
  <vuosimalli>1955</vuosimalli>
</auto>

Ulkoiset entiteetit

XML tukee myös ulkoisten entiteettien käyttöä, jotta XML-dokumentteja voidaan kasata useasta eri osasta. Ulkoinen entiteetti määritetään avainsanalla SYSTEM tai PUBLIC entiteetin nimen jälkeen. Ajattele vaikka kirjaa, jossa on kolme eri kappaletta. Kirja voisi koostua XML-dokumenteista kirja.xml, kappale1.xml, kappale2.xml ja kappale3.xml.

Kappaleiden sisältö voisi olla vaikka:

<kappale>
  Oli synkkä ja myrskyinen yö...
</kappale>

Ja kirja.xml sisältö voisi olla:

<!DOCTYPE kirja[
<!ENTITY kappale1 SYSTEM "kappale1.xml">
<!ENTITY kappale2 SYSTEM "kappale2.xml">
<!ENTITY kappale3 SYSTEM "kappale3.xml">
]>
<kirja>
        &kappale1;
        &kappale2;
        &kappale3;
</kirja>

Näin XML-käsittelijä tulostaisi jotain tämän näköistä, ja kirjan rakenne sekä kappaleet pysyvät kivasti erillään omissa tiedostoissaan.

<kirja>
  <kappale>
    Oli synkkä ja myrskyinen yö...
  </kappale>
  <kappale>
    Sankarimme perille saavuttuaan...
  </kappale>
  <kappale>
    Täysin odottamatta...
  </kappale>
</kirja>

Haavoittuvuus

Jos olet kärryillä tähän asti, niin XXE-haavoittuvuus on melko yksinkertainen ymmärtää. Haavoittuvuudessa on kyse siitä, että:

  • Sovelluksessa on koodia, joka käsittelee XML:ää.
  • Sovelluksen XML-käsittelijää ei ole määritetty estämään ulkoisten entiteettien käyttöä.
  • Hyökkääjä pääsee syöttämään sovellukselle XML:ää käsiteltäväksi.
  • Hyökkääjä pääsee viittaamaan ulkoisilla entiteeteillä palvelimen levyllä oleviin tiedostoihin.
  • Hyökkäjä pääsee lukemaan käsitellyn XML:n joka sisältää hyökkääjän haluaman tiedoston sisällön.

Hyökkääjän on siis mahdollista tällaisissa tapauksissa lukea tiedostoja palvelimen levyltä.

Hyvä tietää jo tässä vaiheessa

XXE-haavoittuvuuksissa ja tavoissa joilla haavoittuvuuksia voi hyväksikäyttää on paljon variaatioita. Riippuen ohjelmointikielestä, XML-käsittelijästä ja alustasta jonka päällä sovellus on ajossa, XXE:llä voi tehdä erilaisia asioita. XML-vastausta ei myöskään ole pakko päästä näkemään, vaan on olemassa tekniikoita joilla tietoja saadaan vuodatettua verkon yli. Palaamme näihin aiheisiin myöhemmin tällä kurssilla.

Harjoitus

Tee alla oleva harjoitus. Tähän mennessä oppimillasi tiedoilla on mahdollista ratkoa tehtävä ja lukea salainen reseptitiedosto palvelimelta.

Reseptivarkaus

Tässä harjoituksessa pääset kokeilemaan XXE-hyökkäystä XML-pohjaista pizzantilauspalvelua vastaan.

Tavoite

Varasta salainen resepti tiedostosta /secret-recipe.txt

Tehtävät

Flag

Löydä lippu (flag) labraympäristöstä ja syötä se alle.

hakatemia pro

Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.

Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.