Исследователь информационной безопасности Лаел Целлье (Lael Cellier) обнаружил две критические уязвимости в клиенте и серверной части Git (CVE-2016-2324 и CVE?2016?2315).

Воспользовавшись ими, злоумышленники могут осуществлять удаленное выполнение кода. Для этого необходимо создать репозиторий с деревом файлов с очень длинными названиями, а затем отправить «пуш» на удаленный уязвимый сервер или позволить уязвимому клиенту осуществить «пулл».

Две ошибки, приводящие к проблемам, содержатся в функции под названием path_name(), которая используется для добавления имени файла к концу пути в дереве репозитория. Путь и название файла могут быть использованы злоумышленником для запуска зловредного кода — для осуществления успешной атаки необходимо преодолеть различные средства защиты, вроде ASLR, но сделать это можно.

Вот так выглядел код revision.c для Git версий до 2.7.0:

char *path_name(const struct name_path *path, const char *name)
{
        const struct name_path *p;
        char *n, *m;
        int nlen = strlen(name);
        int len = nlen + 1;

        for (p = path; p; p = p->up) {
                if (p->elem_len)
                        len += p->elem_len + 1;
        }
        n = xmalloc(len);
        m = n + len - (nlen + 1);
        strcpy(m, name);
        for (p = path; p; p = p->up) {
                if (p->elem_len) {
                        m -= p->elem_len + 1;
                        memcpy(m, p->elem, p->elem_len);
                        m[p->elem_len] = '/';
                }
        }
        return n;
}

Ошибки в коде приводят к возможности возникновения целочисленного переполнения и переполнения буфера.

Кроме того, исследователям Positive Technologies удалось создать действующий эксплоит. Уязвимость CVE-2016-1285 заключается в недостаточной проверки типов полей управляющего пакета RNDC. Специальным образом сформированный пакет может вызвать assertion failure в модулях sexpr.c или alist.c. Для проведения атаки неаутентифицированный злоумышленник должен находиться в сети, от которой named разрешено принимать управляющие пакеты (секция control файла named.conf).

Пакеты, передаваемые транспортом TCP имеют табличную структуру поле-значение, в которой различные поля могут быть бинарными данными, вложенными таблицами или списками.

Вот так выглядит код, отвечающий за проверку авторизации lib/isccc/cc.c:

        _auth = isccc_alist_lookup(alist, "_auth");
        if (_auth == NULL)
                return (ISC_R_FAILURE);
        if (algorithm == ISCCC_ALG_HMACMD5)
                hmac = isccc_alist_lookup(_auth, "hmd5");
        else
                hmac = isccc_alist_lookup(_auth, "hsha");
        if (hmac == NULL)
                return (ISC_R_FAILURE);

image

Суть патча, закрывающего уязвимость, состоит в дополнительной проверке результата функции isccc_alist_lookup:

Например, diff по этой ссылке:

        _auth = isccc_alist_lookup(alist, "_auth");                                                                                                                    
-       if (_auth == NULL)
+       if (!isccc_alist_alistp(_auth))
                return (ISC_R_FAILURE);


Функция isccc_alist_alistp производит дополнительную проверку вложенных полей:
isccc_alist_alistp(isccc_sexpr_t *alist)

{
        isccc_sexpr_t *car;
 
        if (alist == NULL || alist->type != ISCCC_SEXPRTYPE_DOTTEDPAIR)
                return (ISC_FALSE);
        car = CAR(alist);
        if (car == NULL || car->type != ISCCC_SEXPRTYPE_STRING)
                return (ISC_FALSE);
        if (strcmp(car->value.as_string, ALIST_TAG) != 0)
                return (ISC_FALSE);
        return (ISC_TRUE);
}

Проблемы оставались незамеченными на протяжении нескольких лет — уязвимы версии Git до 2.7.0, включая ветки 1.9 и 1.7. Обе уязвимости были исправлены в версии 2.7.1, которая вышла в феврале 2016 года, однако разработчики Git не объявляли об устранении ошибок, поэтому многие пользователи и администраторы до сих пор не обновили свои системы.

Целлье передал информацию об обнаруженных им уязвимостях в компанию GitHub за что получил 5000 очков в рамках bug bounty программы сервиса — подобные награды даются за обнаружение крайне серьезных уязвимостей.

В дальнейшем сотрудник GitHub исправил ошибки и опубликовала новую версию Git 2.7.1, которая была предоставлена корпоративным пользователям, однако отдельных объявлений об этом сделано не было. GitLab также обновил свое программное обеспечение, реализовав поддержку Git 2.7.3, которая содержит исправления и других ошибок.

Эксперты Positive Technologies рекомендуют всем пользователям и администраторам Git-серверов обновить версию используемого ими программного обеспечения. Скачать новую версию можно по ссылке.

Комментарии (2)


  1. Kanedias
    17.03.2016 00:47
    -9

    Given enough eyeballs, all bugs are shallow, eh? ;)


  1. dimoclus
    17.03.2016 03:11
    +21

    Какая-то чрезвычайно сомнительная уязвимость: возможность запихнуть путь длиной 2Gb уже само по себе может вызвать DoS, когда попытка выделить следующую пару гигабайт под пути закончится ENOMEM-ом.

    Вообще странная пошла мода вешать «критические» ярлыки на всякую минорщину: нет proof of concept эксплоита хотя бы без ASLR => о каком RCE речь?

    P. S. Кстати, в посте замалчивается важная деталь: теоретической возможности RCE нужно «всего лишь» каким-то чдом выставить executable-бит на страницах выделенной памяти, либо иметь W+X страницы с кодом. Даже при отключенном ASLR шансы выполнить что-то злоумышленнически-вразумительное навряд ли будут существенно больше нуля.