Vlákno názorů k článku
Bezpečnostní díra v Java knihovně ohrožuje stovky aplikací od Filip Jirsák - Zprávička zní dost neseriózně, když je v ní...

  • Článek je starý, nové názory již nelze přidávat.
  • 9. 11. 2015 9:30

    Filip Jirsák
    Stříbrný podporovatel

    Zprávička zní dost neseriózně, když je v ní napsáno obecně „Java knihovna“ a nikde v ní není napsáno, která. Ještě pozoruhodnější je, že ta knihovna není pořádně identifikována ani v odkazovaném článku. Pravděpodobně se jedná o knihovnu Apache Commons Collection (dříve součást Apache Jakarta). Navíc podle toho popisu má být chyba v implementaci readObject(), přičemž nikde není popsané, v čem přesně má chyba spočívat – a řešením má být odstranění třídy org.apache.com­mons.collecti­ons.functors.In­vokerTransfor­mer, která v aktuální verzi knihovny ani není, protože se přejmenoval package – a hlavně ta třída neimplementuje metodu readObject().

    Zkrátka je to celé velmi podezřelé a každý by si měl pořádně rozmyslet, než spustí ty údajné exploity – ony to exploity mohou být, ale na něco úplně jiného…

  • 9. 11. 2015 15:38

    Andrei Badea (neregistrovaný)

    Máte pravdu, že popis exploitu je zmatečný.

    Exploit funguje tak, že zaserializuje instanci sun.reflect.an­notation.Anno­tationInvocati­onHandler. Tato třída je z hlediska exploitu zajímavá dvěma aspekty:

    * Má v sobě field java.util.Map memberValues, a
    * Implementuje readObject(), volá v něm defaultReadOb­ject(), a pak iteruje memberValues.en­trySet().

    Exploit místo té mapy zaserializuje instanci LazyMap z commons-collections, obalenou opět v dynamické proxy jejíž handler je opět AnnotationInvo­cationHandler. Zde se AIH používá je na to, že jeho metoda invoke() volá memberValues.get() -- tedy se tím zavolá LazyMap.get().

    LazyMap.get() vytváří prvky on-demand tak, že volá instanci Transformer. Exploit tam dává TransformerChain delegující na řetěz instancí InvocationTran­sformer. InvocationTran­sformer je klíčový pro exploit protože umí volat metody. Konkrétně, tento řetěz InvocationTran­sformerů volá Runtime.getRun­time().exec().

    Takže při deserializaci se přečte top-level AIH a vše co k němu patří, tedy až po řetěz InvocationTran­sformerů, a pak se zavolá AIH.readObject(), to zavolá LazyMap.get() a to zavolá transformery.

    InvocationTran­sformer je tedy klíčový protože kvůli němu neplatí, že deserialzujete jen data. Svým způsobem deserializujete kód.

  • 9. 11. 2015 16:37

    Filip Jirsák
    Stříbrný podporovatel

    Díky za rozbor.

    Na tu třídu InvokerTransformer jsem se díval, ale právě jsem zjistil, že je zneužitelná pouze při zavolání metody transform, pokud útočník může do té metody předat vhodný parametr. A jak se to stane, že se při deserializaci volá ta metoda, to jsem v tom popisu nikde nenašel.

    Podle mne je chyba v implementaci AIH.readObject(), protože to je to místo, kde se při deserializaci najednou místo načítání dat volá kód (i když je pravda, že metoda Map.get() volající kód místo toho, aby jen vrátila data z mapy, je ne příliš časté řešení – ale není to ani porušení kontraktu Map). LazyMap a InvokeTransformer je pak už jenom způsob, jak z volání kódu při deserializaci udělat volání toho správného kódu, který potřebuje útočník – a využívá to toho, že tyhle dvě třídy jsou v jedné docela používané knihovně, takže tam, kde má útočník k dispozici jednu z nich, bude mít i tu druhou.

    Pokud bych měl v aplikaci třeba implementaci mapy, která by jako klíč měla příkaz a vracela třeba návratový kód spuštění příkazu:

    (key) -> Runtime.getInstance().exec(key).waitFor()

    byla by přes AIH.readObject() zneužitelná ještě snáz.

    Akorát že případů jako AIH.readObject() mohou být stovky a podle mne není reálné všechny ošetřit (navíc jediné možné ošetření je, že AIH nebude serializovatelná). Jediné skutečné řešení je tam, kde může do serializovaných dat někdo zasáhnout, nepoužívat způsob serializace, ve kterém může útočník vnutit deserializaci instance libovolné třídy dostupné na classpath.

  • 9. 11. 2015 21:20

    Palo (neregistrovaný)

    Najdolezitejsia je cast:
    > find a part of the application that takes a serialized object as input

    Takuto aplikaciu som nikdy nenapisal lebo je to dost blby napad. A o ziadnej ani neviem. Ziadny kod sa tam neda z webu nahrat, da sa iba zavolat metoda ktoru ste volat nechceli. Napriklad System.exit a to je asi tak vsetko.
    Takze staci nebyt blby a nepouzivat Java serializaciu na prenos udajov cez HTTP. Co je vlastne uplne normalne.

  • 9. 11. 2015 23:00

    Filip Jirsák
    Stříbrný podporovatel

    Takuto aplikaciu som nikdy nenapisal lebo je to dost blby napad. A o ziadnej ani neviem.
    Ale víte. Každá aplikace, která něco ukládá a načítá – třeba každý textový editor. Každá aplikace, která pracuje s databází. Každá vícevrstvá aplikace. Jenom ty způsoby serializace a deserializace se liší.

    Ziadny kod sa tam neda z webu nahrat, da sa iba zavolat metoda ktoru ste volat nechceli.
    Proč z webu? Existují i jiné než webové aplikace. Navíc pokud budete mít na classpath vhodné třídy, třeba BCEL, můžete si tam spustit i svůj kód. Nebo tam můžete mít skriptovací jazyky, a ty jsou součástí Oracle JDK od verze 7.

    Napriklad System.exit a to je asi tak vsetko.
    Ono to úplně stačí. System.exit, Runtime,exec, Connection.exe­cute('Drop database')…

    Takze staci nebyt blby a nepouzivat Java serializaciu na prenos udajov cez HTTP.
    Pokud si myslíte, že se serializované objekty mohou předávat jenom přes HTTP, přenechte starost o bezpečnost raději někomu jinému.

  • 10. 11. 2015 7:11

    Filip Jirsák
    Stříbrný podporovatel

    Ne, nepíše. Podívejte se na ten odkazovaný článek – WebLogic je napaden přes protokol T3, OpenNMS přes RMI…

  • 10. 11. 2015 11:17

    Palo (neregistrovaný)

    A kto ma vystrceny T3 do WEBu? Alebo nebodaj RMI?
    Apache reverse proxy je snad minimum co tam ludia davaju alebo iba my sme cudny?
    Diera to je, netvrdim ze nie, ale nie taka velka ako sa snazi autor exploitu naznacit.

  • 10. 11. 2015 12:08

    Filip Jirsák
    Stříbrný podporovatel

    Vy jste tím webem nějaký uhranutý, ne? Asi jste myslel, kdo má T3 nebo RMI „vystrčené do veřejného internetu“. No tak někdo to tak mít může, vždyť jsou ty přístupy chráněné autorizací a mělo by to být bezpečné. A i když to někdo má přístupné jenom z nějaké privátní sítě, pořád není správné, že kdokoli v té síti může ten server třeba vypnout.

    Apache reverse proxy je snad minimum co tam ludia davaju
    Soudní lidé tam Apache reverse proxy nedávají.

    Diera to je, netvrdim ze nie, ale nie taka velka ako sa snazi autor exploitu naznacit.
    To spíš záleží na konkrétní situaci. Horší podle mne je, že ta díra spočívá v něčem jiném, než autoři exploitu naznačují, a hlavně že ten jejich „fix“ zalepí jednu konkrétní díru, kterou zkouší jejich exploit, ale neřeší tu díru jako takovou.

  • 10. 11. 2015 22:11

    Palo (neregistrovaný)

    > kdokoli v té síti
    tam ma pristup iba administrator

    > Soudní lidé tam Apache reverse proxy nedávají.
    Load balancing a fail over riesite ako? Ci pouzivate WebLogic za velke peniaze a mate ho rovno vystrceny do internetu? :-D

    Diera tam ziadna nie je. Iba niekto zle implementoval deserializaciu udajov. Ked naprogramujem ze ked mi odoslete do requestu 'dole' tak sa spusti System.exit to je aka diera?
    Oni spravili kod v custom deserializacnom hooku ktory robi neplechu, to nie je genericka diera.

  • 10. 11. 2015 23:43

    Filip Jirsák
    Stříbrný podporovatel

    Load balancing a fail over riesite ako?
    No tak konkrétně my to řešíme hardwarovým loadbalancerem. Ale některé aplikace jsou rozvažované na úrovni TCP spojení, takže to má hodně blízko k tomu, kdyby ten WebLogic byl přímo vystrčen do internetu?

    Ci pouzivate WebLogic za velke peniaze a mate ho rovno vystrceny do internetu?
    Bojíte se, aby se neošoupal? Já teda tak nějak u dražšího řešení předpokládám, že by mělo být lepší a tudíž i bezpečnější.

    Jinak já jsem narážel na to, že když tak autoritativně zmíníte jedno řešení v situaci, kdy jich existuje n různých podle konkrétních požadavků, nepůsobí to dojmem znalce, o což jste se asi snažil, ale právě naopak.

    Diera tam ziadna nie je. Iba niekto zle implementoval deserializaciu udajov.
    Jo, a když někdo zadá příjmení „Novák'; drop database;“, tak to také není chyba ale jen „zle implementovaná deserializacia udajov“.

    Oni spravili kod v custom deserializacnom hooku ktory robi neplechu, to nie je genericka diera.
    Přečtěte si popis té chyby, je to hned druhý příspěvek v diskusi. Ta třída, která v rámci deserializace spouští neznámý kód, je součástí JRE. To je dost generické. A takových tříd, které nemají readObject() odolný proti útokům, bude spousta. Spuštění kódu, který útočník nikdy neměl mít možnost spustit, je docela průšvih. Samozřejmě by mohl být ještě větší, tady má útočník přeci jen omezené možnosti – vedle té třídy s readObject() potřebuje další vhodné třídy, přes které útok povede (např. ty z Apache Commons Collections).

  • 10. 11. 2015 23:45

    Filip Jirsák
    Stříbrný podporovatel

    Jo, a když někdo zadá příjmení „Novák'; drop database;“,
    Myslel jsem samozřejmě případ, kdy vám tím smaže databázi.

  • 11. 11. 2015 0:24

    Palo (neregistrovaný)

    - Weblogic som nikdy nevidel napriamo vystrceny ani do Intranetu.
    - Program napisal programator, ziadny iny kod sa tam nedostane, ak napisal aby sa urobil drop database tak sa ma urobit
    - Genericky sa ta diera zatvori tak ze na komunikaciu nebudete pouzivat serializovane objekty v HTTP, nikdy v zivote som taku zvrhlost nevidel

  • 11. 11. 2015 7:12

    Filip Jirsák
    Stříbrný podporovatel

    To, že jste něco neviděl, neznamená vůbec nic. A vzhledem k tomu, co tu píšete v komentářích, to neznamená tuplem vůbec nic.

    Pro útočníka zajímavé metody poskytuje i standardní knihovna, třeba System.exit nebo Runtime.exec. K tomu, že útočník může smazat databázi, i když v programu žádný takový kód není – hledejte pojem „SQL injection“. Když má útočník v ruce spojení do databáze a může na něm zavolat libovolný příkaz, má dost silný nástroj.

    To HTTP a web vás opravdu uhranulo. Vězte, že existují i jiné síťové protokoly, než HTTP, a také se přes ně dají přenášet serializované objekty. A dokonce může útočník podvrhnout serializované objekty i do vstupu, který server nedostane síťovým protokolem, ale třeba ze souboru nebo databáze.

  • 11. 11. 2015 8:28

    Palo (neregistrovaný)

    Nie som nicim uhranuty iba mam asi viacej paranoje nez iny. Ak mozete serveru podhadzovat serializovane udaje nieco je zle. Fakt nepoznam aplikaciu ktora deserializuje objekty odkialkolvek. Je to neprenosne, pomale, ... cele zle.
    Ak mate Java aplikaciu nachylnu na SQL Injection opat ste urobili nieco zle v navrhu. V ziadnej nasej instancii nebezi ani console na porte ktory je dostupny mimo pristupu administratora.
    Security sa neobjavi len tak sama. Musite dodrziavat nejake zasady. Neserializovat Java objecty pomocou standardneho Java serialization frameworku je rovnake pravidlo ako pouzivat binding parametrov do SQL. Absolutne zakladna vec.

  • 11. 11. 2015 8:46

    Filip Jirsák
    Stříbrný podporovatel

    To nevím, co s tou vaší paranoií budete dělat, až zjistíte, že existují i jiné protokoly než HTTP. SQL injection jsem uváděl jako příklad toho, co může útočník udělat, pokud dokáže zneužít téhle chyby. Byla to reakce na vaše tvrzení, že je ta chyba nezajímavá, protože útočník nemůže spustit žádný jiný kód, než ten, který je v aplikaci. Pouze dodržování zásad k zajištění bezpečnosti nestačí – je potřeba tomu také rozumět. Jinak dotyčný dopadne jako vy a bude si myslet, že když používá binding parametrů, nemusí se SQL injection bát.

  • 12. 11. 2015 21:42

    Palo (neregistrovaný)

    Jasne, vy ma poznate a vy ste ten perfektny kto rozumie a ostani nerozumeju. :-D
    Jaj ty moj vzdelany debilko. Nechapes ani zakladom.
    Ja som napisal ze ak NEpouzivas BINDING tak si koledujes o SQL injection. Nie ze ak ho pouzivas tak sa vyhnes SQL Injection.
    Takze dostudovat zaklady logiky a potom sa zase mozes ist chvalit na internety.

  • 11. 11. 2015 9:15

    Kolemjdoucí (neregistrovaný)

    Pro všechny kdož mají Weblogic (konkrétně jeho protokol T3) zpřístupněný na síťové úrovni nedůvěryhodným uživatelům už Oracle vydal patch: https://blogs.oracle.com/security/entry/security_alert_cve_2015_4852