For the English version of this alert, click here.
Allele Security Alert
ASA-2019-00011
Identificador(es)
ASA-2019-00011, CVE-2018-16866
Título
Out-of-bounds read ao analisar uma mensagem do syslog criada
Fabricante(s)
Lennart Poettering
Produto(s)
systemd
Versão(ões) afetada(s)
systemd v221 até v240
Versão(ões) corrigida(s)
systemd lançado com os seguintes commits:
journal: fix syslog_parse_identifier()
https://github.com/systemd/systemd/commit/a6aadf4ae0bae185dc4c414d492a4a781c80ffe5
journal: do not remove multiple spaces after identifier in syslog message
https://github.com/systemd/systemd/commit/8595102d3ddde6d25c282f965573a6de34ab4421
Prova de conceito
Desconhecida
Descrição
Um out-of-bounds read foi descoberto no systemd-journald na maneira como ela analisa mensagens de log que terminam com dois pontos ‘:’. Um atacante local pode usar essa vulnerabilidade para divulgar dados da memória de processo.
Detalhes técnicos
Foi descoberto um out-of-bounds read no journald que pode ser transformado em um memory leak:
File: v238/src/journal/journald-syslog.c --- 31 #define WHITESPACE " \t\n\r" ... 194 size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) { 195 const char *p; ... 197 size_t l, e; ... 203 p = *buf; 204 205 p += strspn(p, WHITESPACE); 206 l = strcspn(p, WHITESPACE); 207 208 if (l <= 0 || 209 p[l-1] != ':') 210 return 0; 211 212 e = l; ... 240 if (strchr(WHITESPACE, p[e])) 241 e++; 242 *buf = p + e; 243 return e; 244 } ---
Se enviarmos uma mensagem do syslog para o journald (em *buf), e se o último caractere desta mensagem for um ‘:’ (antes do terminador ‘\0’), então:
– na linha 240, p[e] é o terminador ‘\0’ da nossa mensagem;
– na linha 240, strchr(WHITESPACE, p[e]) retorna um ponteiro para o terminador ‘\0’ da cadeia WHITESPACE (como mencionado em man strchr: “O byte nulo de terminação é considerado parte da cadeia, de forma que se c é especificado como ‘\0’, essas funções retornam um ponteiro para o terminador. “);
– na linha 241, e é incrementado;
– na linha 242, *buf aponta fora dos limites, para o primeiro caracter após o terminador ‘\0’ da nossa mensagem;
– mais tarde, a string fora do limite em *buf (supostamente o corpo da nossa mensagem do syslog) é escrita (vazada) para o journald.
Consequentemente, podemos ler esta string fora dos limites:
– diretamente do journald (se “Storage” do journald for “persistent” ou “auto” e /var/log/ journal/ existe), porque o journald suporta ACLs de arquivos estendidos (Access Control Lists):
$ id uid=1000(john) gid=1000(john) groups=1000(john) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ ls -l /var/log/journal/*/user-$UID.journal -rw-r-----+ 1 root systemd-journal 8388608 Nov 20 09:35 /var/log/journal/2562d1eced654f44a3d3a217d66b9ff3/user-1000.journal $ getfacl /var/log/journal/*/user-$UID.journal ... user:john:r-- $ ./infoleak $ journalctl --all --user --lines=1 --identifier=infoleak | hexdump -C ... 00000050 2e 20 2d 2d 0a 4e 6f 76 20 32 30 20 31 36 3a 30 |. --.Nov 20 16:0| 00000060 30 3a 33 36 20 6c 6f 63 61 6c 68 6f 73 74 2e 6c |0:36 localhost.l| 00000070 6f 63 61 6c 64 6f 6d 61 69 6e 20 69 6e 66 6f 6c |ocaldomain infol| 00000080 65 61 6b 5b 33 35 34 38 5d 3a 20 78 fb 1e 78 54 |eak[3548]: x..xT| 00000090 7f 0a |..|
– ou (se o “Storage” do journald é “volatile“, ou “auto” e /var/log/journal/ não existe) de um tty que gravamos para /var/run/utmp, porque journald escreve (“walls“) mensagens de emergência (LOG_EMERG) para o tty de cada usuário logado:
$ ./infoleak ... 00003510 0a 07 0d 0d 0a 42 72 6f 61 64 63 61 73 74 20 6d |.....Broadcast m| 00003520 65 73 73 61 67 65 20 66 72 6f 6d 20 73 79 73 74 |essage from syst| 00003530 65 6d 64 2d 6a 6f 75 72 6e 61 6c 64 40 6c 6f 63 |emd-journald@loc| 00003540 61 6c 68 6f 73 74 2e 6c 6f 63 61 6c 64 6f 6d 61 |alhost.localdoma| 00003550 69 6e 20 28 54 75 65 20 32 30 31 38 2d 31 31 2d |in (Tue 2018-11-| 00003560 32 30 20 31 36 3a 32 35 3a 34 36 20 43 53 54 29 |20 16:25:46 CST)| 00003570 3a 0d 0d 0a 0d 0d 0a 69 6e 66 6f 6c 65 61 6b 5b |:......infoleak[| 00003580 33 38 37 32 5d 3a 20 78 6b a2 e1 2f 7f 0d 0d 0a |3872]: xk../....|
Esta vulnerabilidade foi introduzida no systemd v221:
commit ec5ff4445cca6a1d786b8da36cf6fe0acc0b94c8 Date: Wed Jun 10 22:33:44 2015 -0700 ... - e += strspn(p + e, WHITESPACE); + if (strchr(WHITESPACE, p[e])) + e++;
e foi inadvertidamente corrigido em agosto de 2018:
commit a6aadf4ae0bae185dc4c414d492a4a781c80ffe5 Date: Wed Aug 8 15:06:36 2018 +0900 ... - if (strchr(WHITESPACE, p[e])) - e++; + e += strspn(p + e, WHITESPACE);
commit 8595102d3ddde6d25c282f965573a6de34ab4421 Date: Fri Aug 10 11:07:54 2018 +0900 ... - e += strspn(p + e, WHITESPACE); + /* Single space is used as separator */ + if (p[e] != '\0' && strchr(WHITESPACE, p[e])) + e++;
Créditos
Qualys Research Labs
Referência(s)
System Down: A systemd-journald exploit
https://seclists.org/oss-sec/2019/q1/54
journal: fix syslog_parse_identifier()
https://github.com/systemd/systemd/commit/a6aadf4ae0bae185dc4c414d492a4a781c80ffe5
journal: do not remove multiple spaces after identifier in syslog message
https://github.com/systemd/systemd/commit/8595102d3ddde6d25c282f965573a6de34ab4421
CVE-2018-16866
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16866
CVE-2018-16866
https://nvd.nist.gov/vuln/detail/CVE-2018-16866
Se encontrou algum erro neste alerta ou deseja uma análise compreensiva, entre em contato.
Última modificação: 14 agosto 2019