ASA-2019-00465 – Linux kernel: Tratamento equivocado de permissão e ciclo de vida de objeto para PTRACE_TRACEME


For the English version of this alert, click here.

Allele Security Alert

ASA-2019-00465

Identificador(es)

ASA-2019-00465, CVE-2019-13272

Título

Tratamento equivocado de permissão e ciclo de vida de objeto para PTRACE_TRACEME

Fabricante(s)

Linux foundation

Produto(s)

Linux kernel

Versão(ões) afetada(s)

Linux kernel versões desde a 4.10

Linux kernel versões contendo o seguinte commit:

ptrace: Capture the ptracer’s creds not PT_PTRACE_CAP
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=64b875f7ac8a5d60a4e191479299e931ee949b67

Versão(ões) corrigida(s)

Linux kernel versão 5.2

Linux kernel stable versão 4.4.185
Linux kernel stable versão 4.9.185
Linux kernel stable versão 4.14.133
Linux kernel stable versão 4.19.58
Linux kernel stable versão 5.1.17

Prova de conceito

Sim

Descrição

Foi encontrada uma falha na maneira como a funcionalidade PTRACE_TRACEME era manipulada no kernel do Linux. A implementação do ptrace no kernel pode inadvertidamente conceder permissões elevadas a um atacante que pode abusar do relacionamento entre o tracer e o processo que está sendo traced. Essa falha pode permitir que um usuário local, sem privilégios, aumente seus privilégios no sistema ou cause uma negação de serviço.

Detalhes técnicos

Os relacionamentos ptrace podem ser configurados de duas maneiras:

O tracer é conectado a outro processo (PTRACE_ATTACH/PTRACE_SEIZE) ou o tracee força o pai a se conectar a ele (PTRACE_TRACEME). Quando uma tracee passa por um execve() que obtém privilégio, o kernel verifica se o relacionamento ptrace é privilegiado. Se não for, o efeito de ganho de privilégio de execve é suprimido. A idéia aqui é que um tracer privilegiado (por exemplo, se a raiz executa “strace” em algum processo) pode rastrear a execução setuid/setcap, mas um tracer não privilegiado não deve ter permissão para fazer isso, pois poderia injetar código arbitrário em processos privilegiados.

No caso PTRACE_ATTACH/PTRACE_SEIZE, as credenciais do tracer são registradas no momento em que ele chama PTRACE_ATTACH/PTRACE_SEIZE; mais tarde, quando o tracee passa por execve(), é verificado se as credenciais registradas são capazes sobre o namespace de usuário do tracee. Mas no caso PTRACE_TRACEME, o kernel também registra as credenciais do tracer, mesmo que o tracer não esteja solicitando a operação. Existem dois problemas com isso.

Primeiro, há um problema de vida útil do objeto:

ptrace_traceme() -> ptrace_link() obtém __task_cred(new_parent) em uma seção crítica RCU read-side e, em seguida, passa as credenciais para __ptrace_link(), que chama get_cred() nelas. Se o pai alterna suas creds simultaneamente (por exemplo, via setresuid()), o reference counter das creds já pode ser zero, caso em que put_cred_rcu() já terá sido agendada. O kernel geralmente consegue entrar em panic() antes que ocorra corrupção de memória usando o seguinte código em put_cred_rcu(). No entanto, a corrupção de memória também seria possível se esse código fosse executado exatamente da maneira correta.

 if (atomic_read(&cred->usage) != 0)
     panic("CRED: put_cred_rcu() sees %p with usage %d\n", cred, atomic_read(&cred->usage));

O segundo problema é que, como o caso PTRACE_TRACEME captura as credenciais de um tracer potencialmente inconsciente, pode ser possível para um usuário normal criar e usar um relacionamento ptrace marcado como privilegiado, mesmo que nenhum código privilegiado tenha solicitado ou usado esse relação ptrace. Isso requer a presença de um binário setuid com determinado comportamento: ele precisa eliminar privilégios e então tornar-se dumpable novamente (via prctl() ou execve()).

task A: fork() cria um child, tarefa B
task B: fork() cria um child, tarefa C
task B: execve(/some/special/suid/binary)
task C: PTRACE_TRACEME (cria relacionamento privilegiado ptrace)
task C: execve(/usr/bin/passwd)
task B: descartar privilégios (setresuid(getuid(), getuid(), getuid()))
task B: tornar-se dumpable novamente (por exemplo, execve(/some/other/binary))
task A: PTRACE_ATTACH para a task B
task A: use ptrace para assumir o controle da tarefa B
task B: use ptrace para assumir o controle da tarefa C

O helper pkexec do Polkit se encaixa nesse padrão. Em um sistema desktop típico, qualquer processo executado em uma sessão local ativa pode chamar alguns helpers por meio do pkexec (consulte configuração em /usr/share/polkit-1/actions, procure por <action>s que especifique <allow_active> yes </allow_active> e <annotate key=”org.freedesktop.policykit.exec.path”> …</annotate>).

Enquanto pkexec é normalmente usado para rodar programas como root, pkexec na verdade permite que seu chamador especifique o usuário para executar um comando como com –user, que permite usar o pkexec para executar um comando como o usuário que executou o pkexec.

Créditos

Jann Horn (Google Project Zero)

Referência(s)

Issue 1903: Linux: broken permission and object lifetime handling for PTRACE_TRACEME
https://bugs.chromium.org/p/project-zero/issues/detail?id=1903

ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6994eefb0053799d2e07cd140df6c2ea106c41ee

ptrace: Capture the ptracer’s creds not PT_PTRACE_CAP
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=64b875f7ac8a5d60a4e191479299e931ee949b67

Linux 5.2
https://lore.kernel.org/lkml/CAHk-=whtW3FdruS-q2zehJPSan1SKtHoFHKX28A3J_1gfTFUMw@mail.gmail.com/

ChangeLog-4.4.185
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.4.185

ChangeLog-4.9.185
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.9.185

ChangeLog-4.14.133
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.14.133

ChangeLog-4.19.58
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.19.58

ChangeLog-5.1.17
https://cdn.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.1.17

CVE-2019-13272 Linux local root exploit
https://github.com/jas502n/CVE-2019-13272

CVE-2019-13272
https://access.redhat.com/security/cve/CVE-2019-13272

CVE-2019-13272 in Ubuntu
https://people.canonical.com/~ubuntu-security/cve/CVE-2019-13272.html

CVE-2019-13272 | SUSE
https://www.suse.com/security/cve/CVE-2019-13272

CVE-2019-13272
https://security-tracker.debian.org/tracker/CVE-2019-13272

CVE-2019-13272
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13272

CVE-2019-13272
https://nvd.nist.gov/vuln/detail/CVE-2019-13272

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

Última modificação: 8 dezembro 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.