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