GHOST, czyli poważny błąd bezpieczeństwa w glibc

GHOST, czyli poważny błąd bezpieczeństwa w glibc

    przez -
    17 743
    Bezpieczeństwo i szyfrowanie
    Pracownicy firmy Qualys poinformowali o poważnym błędzie bezpieczeństwa – CVE-2015-0235 w popularnej linuksowej bibliotece glibc. Podatność otrzymała kryptonim o nazwie GHOST, a za jej pomocą atakujący może przejąć całkowitą kontrolę nad serwerem. Atak można przeprowadzić zdalnie lub lokalnie, a podatne na ową lukę mogą być, ale nie muszą aplikacje: Apache, CUPS, Dovecot, GnuPG, isc-dhcp, Lighttpd, MariaDB, MySQL, nfs-utils, nginx, nodejs, OpenLDAP, OpenSSH, Postfix, proftpd, pure-ftpd, rsyslog, Samba, sendmail, sysklogd, syslog-ng, tcp_wrappers, vsftpd i xinetd.

    Luka GHOST to typowy atak z przepełnieniem bufora (buffer overflow), który został znaleziony w funkcji __nss_hostname_digits_dots() biblioteki glibc. Służy ona do zamiany nazw DNS na adresy IP (i na odwrót). Warto zaznaczyć, że podatne są wszystkie aplikacje, korzystające z protokołu DNS poprzez funkcje z rodziny gethostbyname*().

    Autorzy udostępniają też niewielki kod w języku C, sprawdzający czy jesteśmy podatni czy nie:

    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    
    #define CANARY "in_the_coal_mine"
    
    struct {
      char buffer[1024];
      char canary[sizeof(CANARY)];
    } temp = { "buffer", CANARY };
    
    int main(void) {
      struct hostent resbuf;
      struct hostent *result;
      int herrno;
      int retval;
    
      /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/
      size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;
      char name[sizeof(temp.buffer)];
      memset(name, '0', len);
      name[len] = '\0';
    
      retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);
    
      if (strcmp(temp.canary, CANARY) != 0) {
        puts("vulnerable");
        exit(EXIT_SUCCESS);
      }
      if (retval == ERANGE) {
        puts("not vulnerable");
        exit(EXIT_SUCCESS);
      }
      puts("should not happen");
      exit(EXIT_FAILURE);
    }
    

    Sprawdzenia można dokonać przy pomocy poniższych poleceń:

    cd /usr/src
    wget https://gist.githubusercontent.com/koelling/ef9b2b9d0be6d6dbab63/raw/de1730049198c64eaf8f8ab015a3c8b23b63fd34/gistfile1.c --no-check-certificate
    gcc gistfile1.c -o CVE-2015-0235
    ./CVE-2015-0235
    

    Łatki zostały udostępnione przez: Red Hat (Bug 1183461), Canonical (USN-2485-1), Debiana (CVE-2015-0235).

    Po aktualizacji należy zrestartować wszystkie usługi, które wykorzystują glibc, a najlepiej jest zrobić restart serwera:

    lsof | grep libc | awk '{print $1}' | sort | uniq

    Warto spojrzeć sobie na historię błędu GHOST, ponieważ pierwsze zgłoszenie zostało zarejestrowane już 12 stycznia 2013 roku i nadano mu numer Bug 15014. Poprzednia luka została naprawiona 21 maja 2013 roku, jednakże nie nadano jest statusu błędu krytycznego, przez co wiele systemów nie zrobiło aktualizacji do najnowszej wersji.

    Ciekawy wydaje się również 4 komentarz, który brzmi następująco:

    Florian *has* reviewed over 3000 past glibc bugs for security impact
    (there are a fair number more, mostly older bugs, not yet given a security
    flag), but as this case illustrates it may not be apparent from the bug
    description that a buffer overrun was involved at all (the subject of this
    bug rather suggests a conformance issue with a wrong errno value).

    Now, if someone else wants to do their own review of over 3000 bugs with
    “security-” flag, and to query cases where they disagree with that
    assessment, that would be welcome, but probably also very tedious and not
    likely to find many cases of misclassified bugs.

    Wynika z niego, że w glibc zostało przejrzanych ponad 3000 błędów wstecz, ale żaden póki co nie otrzymał statusu krytycznego. Deweloperzy zalecają także samodzielne przeszukanie i zgłoszenie ewentualnych uwag.

    • Tam gdzie się da:

      yum clean all
      yum update –disableexcludes=all -y
      reboot

      ;-)

      • `apt-get clean && apt-get update && apt-get upgrade`

        tam, gdzie `yum` nie pomoże :)

      • Roman

        Menu start -> Settings -> Aktualizacje i odzyskiwanie -> Windows Update -> Sprawdź aktualizacje

      • A jak będzie w Mac OS X? Tam trzeba płacić? :P

      • Roman

        Po co mówić o systemie, którzy tworzą kreatorzy mody.

        Jabłko->App Store->Updates

      • Jakub Konieczny

        Ale to dopiero za miesiąc, bo teraz ta łatka (o ile już jest) znowu wifi wyłączy.

    • johhny

      pacman -Syu
      tam gdzie apt-get nie ma :P

    • Roman

      Miliony oczu

      • TheBlackMan_dq

        Miliony monet

    • Jakub Konieczny

      Od chyba tygodnia olewam powiadomienie o aktualizacji i jest niewrażliwy na ten bug, jak czytałem po innych stronach to też mało kto ma system wrażliwy na to. Media znów paniki sieją, bo „luka w Linuksie, taki niebezpieczny, kupcie Windowsa”.

    • o_O

      Ciekawe przez jaki czas NSA wykorzystywała tą lukę :D

    • Luke_l

      Zauważyłem, że po aktualizacji glibc przestała działać poprawnie komenda uniq. Wcześniej użycie uniq -cd pięknie zwracało duplikaty, a teraz nic nie zwraca. Na dodatek jak użyje uniq -c to jeśli coś na liście pojawi się trzykrotnie, to zwraca, że wystąpiło dwukrotnie, a dla dwukrotnych wystąpień nic nie zwraca. Czy ktoś ma podobnie?

      • Na jakim systemie?

      • Luke_l

        Scientific Linux 7

      • Luke_l

        Fałszywy alarm. Pomyłka.