
Exploração de escalada de privilégios no Linux via snapd (CVE-2019-7304)
Em janeiro de 2019, versões atuais do Ubuntu Linux foram consideradas vulneráveis à escalação de privilégios local devido a um bug na API do snapd. Este repositório contém o POC original do exploit, que está sendo disponibilizado para pesquisa e educação. Para uma explicação detalhada da vulnerabilidade e do exploit, consulte a postagem no blog aqui.
O Ubuntu vem com snapd por padrão, mas qualquer distribuição deve ser explorável se tiver este pacote instalado. Você pode verificar facilmente se seu sistema é vulnerável. Execute o comando abaixo. Se seu snapd for 2.37.1 ou mais recente, você está seguro.
$ snap version
...
snapd 2.37.1
...
Observe que alguns sistemas retornam a versão do pacote de distribuição do snapd quando você executa este comando, ao contrário da versão upstream mostrada no exemplo acima. Se sua versão do snapd tiver uma referência a algo como um número de versão do Ubuntu anexado a ela (exemplo: 2.34.2ubuntu0.1 ou 2.35.5+18.10.1, então consulte este link para determinar se você está executando uma versão corrigida.
Este exploit contorna as verificações de controle de acesso para usar uma função de API restrita (POST /v2/create-user) do serviço local snapd. Isso consulta o Ubuntu SSO por um nome de usuário e chave SSH pública de um endereço de e-mail fornecido e, em seguida, cria um usuário local baseado nesses valores.
A exploração bem-sucedida para esta versão requer uma conexão de Internet de saída e um serviço SSH acessível via localhost.
Para explorar, primeiro crie uma conta no Ubuntu SSO. Após confirmá-la, edite seu perfil e faça upload de uma chave SSH pública. Em seguida, execute o exploit assim (com a chave SSH privada correspondente à chave pública que você enviou):
python3 ./dirty_sockv1.py -u "[email protected]" -k "id_rsa"
[+] Slipped dirty sock on random socket file: /tmp/ktgolhtvdk;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Sending payload...
[+] Success! Enjoy your new account with sudo rights!
[Script will automatically ssh to localhost with the SSH key here]
Este exploit contorna as verificações de controle de acesso para usar uma função de API restrita (POST /v2/snaps) do serviço local snapd. Isso permite a instalação de snaps arbitrários. Snaps em "devmode" contornam a sandbox e podem incluir um "hook de instalação" que é executado no contexto do root no momento da instalação.
dirty_sockv2 aproveita a vulnerabilidade para instalar um snap "devmode" vazio incluindo um hook que adiciona um novo usuário ao sistema local. Esse usuário terá permissões para executar comandos sudo.
Ao contrário da versão um, esta não requer que o serviço SSH esteja em execução. Também funcionará em versões mais recentes do Ubuntu sem conexão com a Internet, tornando-a resiliente a mudanças e eficaz em ambientes restritos.
Nota para clareza: Esta versão do exploit não se esconde dentro de um snap malicioso. Em vez disso, usa um snap malicioso como mecanismo de entrega para o payload de criação de usuário. Isso é possível devido ao mesmo bug uid=0 da versão 1
Este exploit também deve ser eficaz em sistemas não Ubuntu que tenham snapd instalado, mas que não suportem a API "create-user" devido à sintaxe de shell Linux incompatível.
Alguns sistemas Ubuntu mais antigos (como 16.04) podem não ter os componentes do snapd instalados que são necessários para sideloading. Se for o caso, esta versão do exploit pode acionar a instalação dessas dependências. Durante essa instalação, o snapd pode se atualizar para uma versão não vulnerável. Os testes mostram que o exploit ainda é bem-sucedido neste cenário. Consulte a seção de solução de problemas para mais detalhes.
Para explorar, simplesmente execute o script sem argumentos em um sistema vulnerável.
python3 ./dirty_sockv2.py
[+] Slipped dirty sock on random socket file: /tmp/gytwczalgx;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Deleting trojan snap (and sleeping 5 seconds)...
[+] Installing the trojan snap (and sleeping 8 seconds)...
[+] Deleting trojan snap (and sleeping 5 seconds)...
********************
Success! You can now `su` to the following account and use sudo:
username: dirty_sock
password: dirty_sock
********************
Se estiver usando a versão dois e o exploit for concluído, mas você não vir sua nova conta, isso pode ser devido a algumas atualizações de snap em segundo plano. Você pode visualizá-las executando snap changes e depois snap change #, referenciando a linha que mostra a instalação do snap dirty_sock. Eventualmente, elas devem ser concluídas e sua conta deve estar utilizável.
A versão 1 parece ser a mais fácil e rápida, se seu ambiente suportá-la (serviço SSH em execução e acessível a partir de localhost).
Sistemas não vulneráveis produzirão algo como o seguinte:
[!] System may not be vulnerable, here is the API reply:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
Date: Mon, 18 Feb 2019 07:07:12 GMT
Content-Length: 119
{"type":"error","status-code":401,"status":"Unauthorized",
"result":{"message":"access denied","kind":"login-required"}}
Por favor, abra issues para qualquer coisa estranha.
O problema foi reportado diretamente à equipe do snapd através do rastreador de bugs do Ubuntu. Você pode ler o tópico completo aqui.
Fiquei muito impressionado com a resposta da Canonical a este problema. A equipe foi incrível de trabalhar, e no geral a experiência me faz sentir muito bem por ser um usuário do Ubuntu.
Links de aviso público:
Nota: Estou postando informações apenas neste repositório GitHub, meu blog em initblog.com e o blog da minha equipe em shenaniganslabs.io. Qualquer site que se passar por fonte oficial está, infelizmente, fora do meu controle.