ASA-2019-00009 – systemd: Stack overflow ao chamar syslog de um comando com cmdline longo


For the English version of this alert, click here.

Allele Security Alert

ASA-2019-00009

Identificador(es)

ASA-2019-00009, CVE-2018-16864

Título

Stack overflow ao chamar syslog de um comando com cmdline longo

Fabricante(s)

Lennart Poettering

Produto(s)

systemd

Versão(ões) afetada(s)

systemd v203 até v240

Versão(ões) corrigida(s)

systemd lançado com o seguinte commit:

journald: do not store the iovec entry for process commandline on stack
https://github.com/systemd/systemd/pull/11374/commits/084eeb865ca63887098e0945fb4e93c852b91b0f

Prova de conceito

Desconhecida

Descrição

Uma alocação de memória sem limites, que poderia resultar em stack clash com outra região de memória, foi descoberta no systemd-journald quando um programa com argumentos de linha de comando longos chama syslog. Um atacante local pode usar essa falha para travar o systemd-journald ou escalação de privilégios.

Detalhes técnicos

Passando vários megabytes de argumentos da linha de comando para um programa que chama syslog(), causa o journald travar:

systemd-journal[472]: segfault at 7ffe9a077420 ip 00007f45f6174877 sp 00007ffe9a0773f0 error 6 in systemd-journald[7f45f6169000+3f000]
(gdb) disassemble 0x7f45f6174877 - 0x7f45f6169000
Dump of assembler code for function dispatch_message_real.4064:
...
0x000000000000b82c <+988>: callq 0x2bd10 
0x000000000000b831 <+993>: test %eax,%eax
0x000000000000b833 <+995>: js 0xb8ea <dispatch_message_real.4064+1178>
0x000000000000b839 <+1001>: mov -0x218(%rbp),%rbx
0x000000000000b840 <+1008>: test %rbx,%rbx
0x000000000000b843 <+1011>: je 0xd31b <dispatch_message_real.4064+7883>
0x000000000000b849 <+1017>: mov %rbx,%rdi
0x000000000000b84c <+1020>: callq 0x5360 <strlen@plt>
0x000000000000b851 <+1025>: add $0xa,%eax
0x000000000000b854 <+1028>: cltq
0x000000000000b856 <+1030>: add $0x1e,%rax
0x000000000000b85a <+1034>: and $0xfffffffffffffff0,%rax
0x000000000000b85e <+1038>: sub %rax,%rsp
0x000000000000b861 <+1041>: movabs $0x454e494c444d435f,%rax
0x000000000000b86b <+1051>: lea 0x37(%rsp),%r15
0x000000000000b870 <+1056>: and $0xfffffffffffffff0,%r15
0x000000000000b874 <+1060>: test %rbx,%rbx
0x000000000000b877 <+1063>: mov %rax,(%r15)
0x000000000000b87a <+1066>: mov $0x3d,%eax
0x000000000000b87f <+1071>: mov %ax,0x8(%r15)
0x000000000000b884 <+1076>: lea 0x9(%r15),%rax
0x000000000000b888 <+1080>: je 0xb895 <dispatch_message_real.4064+1093>
0x000000000000b88a <+1082>: mov %rbx,%rsi
0x000000000000b88d <+1085>: mov %rax,%rdi
0x000000000000b890 <+1088>: callq 0x5370 <stpcpy@plt>
File: v219/src/journal/journald-server.c
---
538 static void dispatch_message_real(
...
604 r = get_process_cmdline(ucred->pid, 0, false, &t);
605 if (r >= 0) {
606 x = strjoina("_CMDLINE=", t);
---
File: v219/src/shared/util.h
---
919 #define strjoina(a, ...) \
920 ({ \
921 const char *_appendees_[] = { a, __VA_ARGS__ }; \
922 char *_d_, *_p_; \
923 int _len_ = 0; \
924 unsigned _i_; \
925 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
926 _len_ += strlen(_appendees_[_i_]); \
927 _p_ = _d_ = alloca(_len_ + 1); \
928 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
929 _p_ = stpcpy(_p_, _appendees_[_i_]); \
930 *_p_ = 0; \
931 _d_; \
932 })
---

Esta vulnerabilidade, um alloca() controlado pelo atacante na instrução 0xb85e e na linha 927, foi introduzida no systemd v203:

commit ae018d9bc900d6355dea4af05119b49c67945184
Date: Mon Apr 22 23:10:13 2013 -0300
...
r = get_process_cmdline(ucred->pid, 0, false, &t);
if (r >= 0) {
- cmdline = strappend("_CMDLINE=", t);
+ cmdline = strappenda("_CMDLINE=", t);

(strappenda() foi renomeado para strjoina() no systemd v219) e se tornou explorável no systemd v230:

commit ac2e41f5103ce2c679089c4f8fb6be61d7caec07
Date: Fri Feb 12 04:59:57 2016 -0800
...
This adds a wait flag to journal_file_set_offline(), when false the offline is
performed asynchronously in a separate thread.

Créditos

Qualys Research Labs

Referência(s)

System Down: A systemd-journald exploit
https://seclists.org/oss-sec/2019/q1/54

journald: do not store the iovec entry for process commandline on stack
https://github.com/systemd/systemd/pull/11374/commits/084eeb865ca63887098e0945fb4e93c852b91b0f

1653855 (CVE-2018-16864) – CVE-2018-16864 systemd: stack overflow when calling syslog from a command with long cmdline
https://bugzilla.redhat.com/show_bug.cgi?id=1653855

CVE-2018-16864
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16864

CVE-2018-16864
https://nvd.nist.gov/vuln/detail/CVE-2018-16864

Se encontrou algum erro neste alerta ou deseja uma análise compreensiva, entre em contato.

Última modificação: 31 janeiro 2019

Não somos responsáveis por qualquer perda de dados, corrupção de dispositivos ou qualquer outro tipo de problema devido ao uso de qualquer informação mencionada em nossos alertas de segurança.