For the English version of this alert, click here.
Allele Security Alert
ASA-2019-00485
Identificador(es)
ASA-2019-00485, CVE-2019-14198
Título
memcpy sem definição de limite com falha na verificação de tamanho nas funções
nfs_read_reply()/store_block()
Fabricante(s)
DENX Software Engineering
Produto(s)
Das U-Boot
Versão(ões) afetada(s)
Desconhecido
Versão(ões) corrigida(s)
Desconhecido
Prova de conceito
Desconhecido
Descrição
O problema existe no caso NFSv3 na função nfs_read_reply() ao ler um arquivo e armazená-lo em outro meio (flash ou memória física) para processamento posterior. Os dados e a duração são totalmente controlados pelo usuário e nunca são validados.
Detalhes técnicos
static int nfs_read_reply(uchar *pkt, unsigned len)
{ [...]
if (supported_nfs_versions & NFSV2_FLAG) {
rlen = ntohl(rpc_pkt.u.reply.data[18]); // <-- rlen is attacker-controlled could be 0xFFFFFFFF
data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]);
} else { /* NFSV3_FLAG */
int nfsv3_data_offset =
nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
/* count value */
rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]); // <-- rlen is attacker-controlled
/* Skip unused values :
EOF: 32 bits value,
data_size: 32 bits value,
*/
data_ptr = (uchar *)
&(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
}
if (store_block(data_ptr, nfs_offset, rlen)) // <-- We pass to store_block source and length controlled by the attacker
return -9999;
[...]
}
Concentrando-se na parte de memória física da função store_block(), ela tenta reservar alguma memória usando a função específica map_physmem(), e chamando phys_to_virt(). É possível observar na implementação x86, ao reservar a memória física, que ela claramente ignora o comprimento e fornece um ponteiro sem verificar se as áreas adjacentes estão reservadas (ou não) para outros propósitos.
static inline void *phys_to_virt(phys_addr_t paddr)
{
return (void *)(unsigned long)paddr;
}
Em seguida, em store_block(), há um memcpy buffer overrun com comprimento e origem controlados pelo usuário.
static inline int store_block(uchar *src, unsigned offset, unsigned len)
{
[...]
void *ptr = map_sysmem(load_addr + offset, len); // <-- essentially this is ptr = load_addr + offset
memcpy(ptr, src, len); // <-- unrestricted overflow happens here
unmap_sysmem(ptr);
[...]
}
Créditos
Fermín Serna, Pavel Avgustinov e Kevin Backhouse
Referência(s)
U-Boot RCE Vulnerabilities Affecting IoT Devices
https://blog.semmle.com/uboot-remote-code-execution-vulnerability/
U-Boot NFS RCE Vulnerabilities (CVE-2019-14192)
https://blog.semmle.com/uboot-rce-nfs-vulnerability/
[U-Boot] Remote code execution vulnerabilities in U-Boot’s NFS and other IP parsing code
https://lists.denx.de/pipermail/u-boot/2019-July/378001.html
CVE-2019-14198
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14198
CVE-2019-14198
https://nvd.nist.gov/vuln/detail/CVE-2019-14198
Se encontrou algum erro neste alerta ou deseja uma análise compreensiva, entre em contato.
Última modificação: 11 agosto 2019