Kto się boi duchów – resztki po GHOST
Ostatnie dni stały pod znakiem sensacyjnego, bo 14-letniego błędu w bibliotece glibc, która czyniła większość dystrybucji linuksowych podatnymi na zdalny atak. Jak to zwykle bywa, błąd został poprawiony niemal z dnia na dzień, a nawet i rok wcześniej (Google naprawiło glibc w Chrome OS i nikomu się nie pochwaliło). Na dodatek, większość współczesnych dystrybucji nie jest rozprowadzana z tym błędem, zatem i poprawki nie są potrzebne. Kto więc jest zagrożony i powinien się naprawiać?
Błąd o kryptonimie GHOST to typowe wykorzystanie przepełnienia bufora (buffer overflow). A można do niego doprowadzić wykorzystując luki w funkcji __nss_hostname_digits_dots() biblioteki glibc. Służy ona do translacji nazw DNS na adresy IP (i na odwrót). Tym samym podatne na ew. zdalny atak są wszystkie programy/usługi korzystające z protokołu DNS i funkcje gethostbyname*(). W momencie ogłoszenia luki podatne na nią były dystrybucje użytkujące starsze wersje glibc:
- RHEL (Red Hat Enterprise Linux) version 5.x, 6.x and 7.x
- CentOS Linux version 5.x, 6.x & 7.x
- Ubuntu Linux version 10.04, 12.04 LTS
- Debian Linux version 7.x
- Linux Mint version 13.0
- Fedora Linux version 19 or older
- SUSE Linux Enterprise 11 and older (also OpenSuse Linux 11 or older versions).
- SUSE Linux Enterprise Software Development Kit 11 SP3
- SUSE Linux Enterprise Server 11 SP3 for VMware
- SUSE Linux Enterprise Server 11 SP3
- SUSE Linux Enterprise Server 11 SP2 LTSS
- SUSE Linux Enterprise Server 11 SP1 LTSS
- SUSE Linux Enterprise Server 10 SP4 LTSS
- SUSE Linux Enterprise Desktop 11 SP3
- Arch Linux glibc version <= 2.18-1
Należy zaznaczyć, że najpopularniejsze Ubuntu 14.04/14.10 nie są podatne na wspomnianą przypadłość.
Aby sprawdzić, czy nasza maszyna jest podatna na tego rodzaju ataki, możemy wykorzystać poniższy kod:
#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);
}
Wystarczy pobrać, skompilować i uruchomić. Martwimy się, jeżeli wynikiem będzie komunikat „vulnerable”. W tym przypadku należy zaktualizować w swojej dystrybucji glibc.
W większości starszych dystrybucji (wspieranych) powinna wystarczyć typowa aktualizacja. Np. Ubuntu 10.04/12.04/Debian:
sudo apt-get clean
sudo apt-get update
sudo apt-get upgrade
I gotowe. Znaleziona luka z pewnością może wydać się sporym ciosem w bezpieczeństwo Linuksa, jednak należy pamiętać, że poprawki dla tego błędu pojawiły się już jakiś czas temu, choć sam błąd nie został uznany za krytyczny. Starsze dystrybucje otrzymały poprawki niemal z dnia na dzień.
#include
#include
?
GHOST zaatakował…