ASA-2019-00123 – Linux: Out-of-bounds read e write no módulo SNMP NAT


For the English version of this alert, click here.

Allele Security Alert

ASA-2019-00123

Identificador(es)

ASA-2019-00123, CVE-2019-9162

Título

Out-of-bounds read e write no módulo SNMP NAT

Fabricante(s)

The Linux foundation

Produto(s)

Linux

Versão(ões) afetada(s)

A vulnerabilidade foi introduzida no seguinte commit:

netfilter: nf_nat_snmp_basic: use asn1 decoder library
https://github.com/torvalds/linux/commit/cc2d58634e0f

Versão(ões) corrigida(s)

Linux kernel 4.14.103
Linux kernel 4.19.25

Prova de conceito

Sim

Descrição

Descobriu-se que há verificações de comprimento de seqüência ASN.1 insuficientes (também conhecido como erro de índice de matriz) no kernel do Linux nas funções snmp_version() e snmp_helper() em net/ipv4/netfilter/nf_nat_snmp_basic_main.c no módulo [nf_nat_snmp_basic] que possibilita out-of-bounds read e write. Um atacante local sem privilégios pode usar essa falha para causar uma condição OOPS do kernel e, assim, uma negação de serviço (DoS). Devido à natureza da falha, um ataque da rede ou escalação de privilégios não pode ser totalmente descartado.

Detalhes técnicos

O commit cc2d58634e0f (“netfilter: nf_nat_snmp_basic: use asn1 decoder library”, primeiro em 4.16) mudou o módulo nf_nat_snmp_basic (que, quando habilitado, analisa e modifica payloads codificadas em ASN.1 de mensagens SNMP) para que a infra-estrutura ASN.1 do kernel seja usada em vez de um analisador de código aberto. O decodificador ASN.1 comum pode invocar callbacks quando determinados objetos são encontrados. O helper SNMP possui duas callbacks definidas em nf_nat_snmp_basic.asn1:

– Para o campo `version` de uma` Message` (um `INTEGER`), snmp_version() é invocado.
– Para cada `IpAddress` (de acordo com o RFC 1155, uma cadeia de octeto de 4 bytes), snmp_helper() é invocado.

Esses retornos de chamada contêm o seguinte código:

int snmp_version(void *context, size_t hdrlen, unsigned char tag, const void *data, size_t datalen)
{
if (*(unsigned char *)data > 1)
return -ENOTSUPP;
return 1;
}
int snmp_helper(void *context, size_t hdrlen, unsigned char tag, const void *data, size_t datalen)
{
struct snmp_ctx *ctx = (struct snmp_ctx *)context;
__be32 *pdata = (__be32 *)data;

if (*pdata == ctx->from) {
pr_debug("%s: %pI4 to %pI4\n", __func__,
(void *)&ctx->from, (void *)&ctx->to);

if (*ctx->check)
fast_csum(ctx, (unsigned char *)data - ctx->begin);
*pdata = ctx->to;
}

return 1;
}

O problema é que ambas as callbacks podem ser invocados pelo analisador ASN.1 com `data` apontando para o final do pacote e `datalen== 0` (embora, para o tipo `INTEGER`, X.690 diz na seção 8.3.1 que “Os octetos de conteúdo devem consistir em um ou mais octetos”), mas eles não verificam se há suficiente entrada disponível. Isso significa que snmp_version() pode ler até um byte fora dos limites e vazar se o byte era <=1, e o snmp_helper() pode ler e potencialmente escrever até quatro bytes out-of-bounds.

Existem dois cenários em que esse bug pode ser atacado:

  1. Um roteador que realiza a tradução NAT é explicitamente configurado para chamar o helper SNMP, e um dispositivo na rede NATted deseja atacar o roteador. Isso é provavelmente muito raro, já que o roteador precisaria ser explicitamente configurado para executar a tradução SNMP. Além disso, para corromper a memória, um atacante precisaria preencher completamente um SKB;
  2. Um atacante local pode explorar o bug configurando novos namespaces de rede com uma configuração iptables que invoca a tradução SNMP. Isso provavelmente funciona como uma escalação de privilégios locais contra alguns kernels de distribuições. O caminho normal de autoloading para este código só foi configurado no commit 95c97998aa9f (“netfilter: nf_nat_snmp_basic: add alias help missing name”, primeiro em 4.20), mas parece que seria possível em kernels antes de 4.20 primeiro carregue um dos aliases do módulo openvswitch “net-pf-16-proto-16-family-ovs_*” através de ctrl_getfamily(), então use ovs_ct_add_helper() para disparar o carregamento de “nf_nat_snmp_basic” através do alias “ip_nat_snmp_basic”.

Créditos

Jann Horn
RedHat

Referência(s)

Issue 1776: Linux: out-of-bounds read and write in SNMP NAT module
https://bugs.chromium.org/p/project-zero/issues/detail?id=1776

Linux kernel: OOB R/W in SNMP NAT module (CVE-2019-9162); virtual address 0 mappable (CVE-2019-9213)
https://seclists.org/oss-sec/2019/q1/166

netfilter: nf_nat_snmp_basic: use asn1 decoder library
https://github.com/torvalds/linux/commit/cc2d58634e0f

netfilter: nf_nat_snmp_basic: add missing length checks in ASN.1 cbs
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c4c07b4d6fa1f11880eab8e076d3d060ef3f55fc

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

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

Bug 1683191 (CVE-2019-9162) – CVE-2019-9162 kernel: out-of-bounds read/write in et/ipv4/netfilter/nf_nat_snmp_basic_main.c in the SNMP NAT module
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2019-9162

Bug 1127324 – (CVE-2019-9162) VUL-1: CVE-2019-9162: kernel-source: net/ipv4/netfilter/nf_nat_snmp_basic_main.c in the SNMP NAT module has insufficient ASN.1 length checks
https://bugzilla.suse.com/show_bug.cgi?id=CVE-2019-9162

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

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

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

Última modificação: 13 março 2019