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

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.