"Tragikusan komikus biztonsági hiba a MySQL-ben"

Kritikus sebezhetőséget javítottak a MySQL és a MariaDB egyes verzióiban. A hiba következtében az adatbázis szerverek hitelesítéskor 1/256 eséllyel rossz jelszó mellett is beengedték a felhasználókat (akár a root-ot is). A problémás verziók megtalálhatók az Ubuntu, OpenSuSE, Fedora és Arch Linux 64 bites disztribúciókban.

A hiba triviálisan kihasználható akár egy egyszerű, egy soros

while true; do mysql -u root mysql --password=barmi; done

futtatással is.

Részletek itt.

Hozzászólások

Nekem nem sikerult reprodukalnom.
mysqld Ver 5.1.61-0ubuntu0.10.10.1-log for debian-linux-gnu on i686 ((Ubuntu)) [Ubuntu 10.10 32 bit - ez ok hogy nem megy]
mysqld Ver 5.1.62-0ubuntu0.11.04.1 for debian-linux-gnu on x86_64 ((Ubuntu)) [Ubuntu 11.04 64 bit - ennek mennie kellene a kiiras alapjan. Frissites nem volt, teljesen alap Ubuntu Server]

--
< huf > sose ertettem h miert kell specialis szo a bunozore, ha szamitogeppel csinalja...
< huf > nemkell se hacker, se cracker se semmi ilyen szo
< huf > fejszes gyilkost se hivjuk favagonak

Ubuntu 12.04: benyelte.

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

Intakt.

Server version: 5.5.23-MariaDB-log Source distribution
OpenSUSE 11.4 x86_64
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Miért nem cikként küldted be? Már elkezdtem írni... :)

Ubuntu: 8.04-en nem, de 12.04-en ment.

while true; do mysql -u root mysql --password=barmi; let i=$i+1; echo $i; done

Hát, az emberek 99.5%-a meg nem mondta volna magától, hogy ez hibás.

Régi: return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
Új: return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE))

#define test(A) ((A) ? 1 : 0)

A függvény my_bool-lal tér vissza, ami igazából "char".

A memcmp implementációját nem ismerem, de úgy tűnik időnként 256 többszörösével tér vissza, ami miatt a my_bool false lesz, így beengedik a klienst.

Miután a legutóbbi HUP-Mónika showban kibeszéltek a C nyelvre rakott megjegyzéseimért, ezért most nem írok inkább semmit.

Tíz percet molyoltam, míg rájöttem, hogy melyik headerben van a 'test' deklarálva.

Én !!memcmp(...)-t használtam volna, mert a programokat manapság PERL-ben írom és a rengeteg krikszkrakszos izé nem kifejezetten zavar.

Mindenesetre nem értem, hogy hogyan lehet a boolean változó alapértelmezésben "char". A legtöbb helyen int-et használnak, gondolom nem véletlenül. Jó lenne tudni, miféle motiváció vezette őket a "char"-ra.

This flaw was rooted in an assumption that the memcmp() function would always return a value within the range -127 to 127 (signed character).

Erre egyszerűen nem tudok mit mondani. Hogy jön itt egy "feltételezés" egyáltalán szóba? Már a C89 is azt mondta, hogy

The memcmp() function returns an integer greater than, equal to, or less than zero, [...]

Ahogy láttam, Te mindig igyekszel az eredeti szabványokat idecitálni, ellenben a programozók zöme (szerintem) ha egyáltalán, akkor max a manuál alapján gondolkodik. Most megnéztem, nálam mi szerepel erről:

RETURN VALUES
The memcmp() function returns zero if the two strings are identical, oth-
erwise returns the difference between the first two differing bytes
(treated as unsigned char values ....

Nos például ez egy olyan megfogalmazás, amit ha csak sima 7-bites ASCII-ben gondolkodik valaki, akkor simán le lehet [-127,127] -nek fordítani.

Ezt atgondoltam en is... de ha valaki a manual alapjan dolgozik, akkor valami ilyesmi kod fog szulettni:


unsigned char ret = memcmp(...);

ebbol signed char-t castolni... hat... nem egy eletbiztositas. De lenyegtelen is, mint latjuk, teljesen maskepp tortent az eset.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

en az int a = memcmp()-re szavaznek. Nalam ugyanis (linuxon):


MEMCMP(3) Linux Programmer's Manual MEMCMP(3)

NAME
memcmp - compare memory areas

SYNOPSIS
#include <string.h>

int memcmp(const void *s1, const void *s2, size_t n);

DESCRIPTION
The memcmp() function compares the first n bytes of the memory areas s1
and s2. It returns an integer less than, equal to, or greater than
zero if s1 is found, respectively, to be less than, to match, or be
greater than s2.

RETURN VALUE
The memcmp() function returns an integer less than, equal to, or
greater than zero if the first n bytes of s1 is found, respectively, to
be less than, to match, or be greater than the first n bytes of s2.

CONFORMING TO
SVr4, 4.3BSD, C89, C99, POSIX.1-2001.

Miert kell nekem sajnalnom a Klubradiot?

Termeszetesen en is erre szavazok. Azonban a kollega hatarozottan masolt egy olyan manualt, ahol uchar van. Erre reagaltam azt, hogy ha valaki meg egy ilyen manual alapjan is dolgozik, akkor is minimum uchar-ra kell ledefinialni a visszateresi valtozot, mert a char az mar castolas, informaciovesztes.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Ahogy láttam, Te mindig igyekszel az eredeti szabványokat idecitálni, ellenben a programozók zöme (szerintem) ha egyáltalán, akkor max a manuál alapján gondolkodik

Rosszul teszik.

A FreeBSD-nél legalább nem szaroztak, kértek és kaptak engedélyt a SUSv3 terjesztésére; náluk az (is) a manual.

returns the difference between the first two differing bytes (treated as unsigned char values

Hamis állítás, dokumentációs hiba. A bug pont erről szól, a memcmp() valamilyen "vektorizált" összehasonlítást végez (legalábbis az SSE említéséből erre következtetek, talán tévesen).

Egyébként is, maradva a fenti (téves) dokumentációnál, a két karakter mindegyike 0 és UCHAR_MAX közötti értéket képvisel (határokat beleértve). Matematikai különbségük -UCHAR_MAX (== 0-UCHAR_MAX) és UCHAR_MAX (== UCHAR_MAX-0) között mozog (határokat beleértve). Ezen intervallum tetszőleges (egész) eleme meglehetős eséllyel (a) kívül esik a [-127, 127]-en, (b) ábrázolható int-ként.

Kiegészítés: a linyuksz manuál böngészése halva született ötlet. Nézzük csak, mit mond a "man memcmp" nálam: This page is part of release 3.22 of the Linux man-pages project. A memcmp() implementáció honnan is származik? (a) glibc, kerneltől / man-pages projekttől független fában fejlesztett projekt, (b) gcc, kerneltől / man-pages projekttől független fában fejlesztett projekt. Esélye sincs nem elavulni a man-pages-nek. Ha már "manuált" akarunk böngészni, akkor ott a glibc info, vagy a gcc info.

Akárhogy is, ezeknél a függvényeknél egyszerűen értelmetlen bármi mást, mint a hivatalos szabványt (leginkább SUSv3-at vagy SUSv4-et) nézni. Épeszű platformfejlesztő azt tekinti specifikációnak és azt implementálja, a manual-ra meg vagy jut ideje, vagy nem. (A saját manual-jára sem.)

A mi fedóránk (F16) bugos, nem fut rajta az "exploit". (5.5.18 MySQL Community Server)
Csaba

Képzeletbeli esemény : cracker csávó gondolja magában, hogy "indítom a brute force-ot, oszt megyek, tolok egy kávét", majd megnyomja az entert.

Azt az arcot...