Jenkins Security
Basic Information
Jenkins é uma ferramenta que oferece um método simples para estabelecer um ambiente de integração contínua ou entrega contínua (CI/CD) para quase qualquer combinação de linguagens de programação e repositórios de código-fonte usando pipelines. Além disso, automatiza várias tarefas de desenvolvimento rotineiras. Embora o Jenkins não elimine a necessidade de criar scripts para etapas individuais, ele fornece uma maneira mais rápida e robusta de integrar toda a sequência de ferramentas de construção, teste e implantação do que se pode facilmente construir manualmente.
Unauthenticated Enumeration
Para procurar páginas interessantes do Jenkins sem autenticação, como (/people ou /asynchPeople, que lista os usuários atuais), você pode usar:
Verifique se você pode executar comandos sem precisar de autenticação:
Sem credenciais, você pode olhar dentro do caminho /asynchPeople/ ou /securityRealm/user/admin/search/index?q= para nomes de usuário.
Você pode conseguir a versão do Jenkins a partir do caminho /oops ou /error
Vulnerabilidades Conhecidas
Login
Nas informações básicas, você pode verificar todas as maneiras de fazer login no Jenkins:
Registro
Você poderá encontrar instâncias do Jenkins que permitem que você crie uma conta e faça login nela. Simples assim.
Login SSO
Além disso, se a funcionalidade/plugins de SSO estiverem presentes, você deve tentar fazer login no aplicativo usando uma conta de teste (ou seja, uma conta de Github/Bitbucket de teste). Dica de aqui.
Bruteforce
Jenkins não possui política de senha e mitigação contra brute-force de nomes de usuário. É essencial fazer brute-force em usuários, uma vez que senhas fracas ou nomes de usuário como senhas podem estar em uso, até mesmo nomes de usuário invertidos como senhas.
Password spraying
Use this python script or this powershell script.
Bypass de Whitelisting de IP
Muitas organizações combinam sistemas de gerenciamento de controle de versão (SCM) baseados em SaaS como GitHub ou GitLab com uma solução de CI interna e auto-hospedada como Jenkins ou TeamCity. Essa configuração permite que os sistemas de CI recebam eventos de webhook de fornecedores de controle de versão SaaS, principalmente para acionar jobs de pipeline.
Para alcançar isso, as organizações whitelist os intervalos de IP das plataformas SCM, permitindo que acessem o sistema de CI interno via webhooks. No entanto, é importante notar que qualquer um pode criar uma conta no GitHub ou GitLab e configurá-la para acionar um webhook, potencialmente enviando solicitações para o sistema de CI interno.
Abusos Internos do Jenkins
Nestes cenários, vamos supor que você tenha uma conta válida para acessar o Jenkins.
Dependendo do mecanismo de Autorização configurado no Jenkins e das permissões do usuário comprometido, você pode ou não ser capaz de realizar os seguintes ataques.
Para mais informações, verifique as informações básicas:
Listando usuários
Se você acessou o Jenkins, pode listar outros usuários registrados em http://127.0.0.1:8080/asynchPeople/
Dumping de builds para encontrar segredos em texto claro
Use this script para despejar saídas de console de builds e variáveis de ambiente de build para, esperançosamente, encontrar segredos em texto claro.
Roubo de Credenciais SSH
Se o usuário comprometido tiver privilegios suficientes para criar/modificar um novo nó Jenkins e as credenciais SSH já estiverem armazenadas para acessar outros nós, ele poderia roubar essas credenciais criando/modificando um nó e definindo um host que registrará as credenciais sem verificar a chave do host:
Você geralmente encontrará credenciais ssh do Jenkins em um provedor global (/credentials/
), então você também pode despejá-las como faria com qualquer outro segredo. Mais informações na seção Despejando segredos.
RCE no Jenkins
Obter um shell no servidor Jenkins dá ao atacante a oportunidade de vazar todos os segredos e variáveis de ambiente e de explorar outras máquinas localizadas na mesma rede ou até mesmo coletar credenciais de nuvem.
Por padrão, o Jenkins executa como SYSTEM. Portanto, comprometê-lo dará ao atacante privilegios de SYSTEM.
RCE Criando/Modificando um projeto
Criar/Modificar um projeto é uma maneira de obter RCE sobre o servidor Jenkins:
RCE Executando script Groovy
Você também pode obter RCE executando um script Groovy, que pode ser mais discreto do que criar um novo projeto:
RCE Criando/Modificando Pipeline
Você também pode obter RCE criando/modificando um pipeline:
Exploração de Pipeline
Para explorar pipelines, você ainda precisa ter acesso ao Jenkins.
Pipelines de Build
Pipelines também podem ser usados como mecanismo de build em projetos, nesse caso pode ser configurado um arquivo dentro do repositório que conterá a sintaxe do pipeline. Por padrão, usa-se /Jenkinsfile
:
Também é possível armazenar arquivos de configuração de pipeline em outros lugares (em outros repositórios, por exemplo) com o objetivo de separar o acesso ao repositório e o acesso ao pipeline.
Se um atacante tiver acesso de escrita sobre esse arquivo, ele poderá modificá-lo e potencialmente acionar o pipeline sem nem mesmo ter acesso ao Jenkins. É possível que o atacante precise contornar algumas proteções de branch (dependendo da plataforma e dos privilégios do usuário, elas podem ser contornadas ou não).
Os gatilhos mais comuns para executar um pipeline personalizado são:
Pull request para a branch principal (ou potencialmente para outras branches)
Push para a branch principal (ou potencialmente para outras branches)
Atualizar a branch principal e esperar até que seja executado de alguma forma
Se você é um usuário externo, não deve esperar criar um PR para a branch principal do repositório de outro usuário/organização e acionar o pipeline... mas se estiver mal configurado, você poderia comprometer totalmente empresas apenas explorando isso.
RCE de Pipeline
Na seção anterior de RCE, já foi indicada uma técnica para obter RCE modificando um pipeline.
Verificando Variáveis de Ambiente
É possível declarar variáveis de ambiente em texto claro para todo o pipeline ou para estágios específicos. Essas variáveis de ambiente não devem conter informações sensíveis, mas um atacante sempre poderia verificar todas as configurações do pipeline/Jenkinsfiles:
Dumping secrets
Para informações sobre como os segredos são geralmente tratados pelo Jenkins, confira as informações básicas:
As credenciais podem ser escopadas para provedores globais (/credentials/
) ou para projetos específicos (/job/<project-name>/configure
). Portanto, para exfiltrar todos eles, você precisa comprometer pelo menos todos os projetos que contêm segredos e executar pipelines personalizados/contaminados.
Há outro problema, para obter um segredo dentro do env de um pipeline, você precisa saber o nome e o tipo do segredo. Por exemplo, se você tentar carregar um segredo usernamePassword
como um segredo string
, você receberá este erro:
Aqui está a maneira de carregar alguns tipos comuns de segredos:
No final desta página você pode encontrar todos os tipos de credenciais: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
A melhor maneira de extrair todos os segredos de uma vez é comprometendo a máquina Jenkins (executando um shell reverso no nó embutido, por exemplo) e então vazando as chaves mestres e os segredos criptografados e descriptografando-os offline. Mais sobre como fazer isso na seção Nodes & Agents e na seção Post Exploitation.
Gatilhos
Das documentações: A diretiva triggers
define as maneiras automatizadas pelas quais o Pipeline deve ser reativado. Para Pipelines que estão integrados com uma fonte como GitHub ou BitBucket, triggers
pode não ser necessário, pois a integração baseada em webhooks provavelmente já estará presente. Os gatilhos atualmente disponíveis são cron
, pollSCM
e upstream
.
Exemplo de Cron:
Verifique outros exemplos na documentação.
Nós e Agentes
Uma instância do Jenkins pode ter diferentes agentes rodando em diferentes máquinas. Do ponto de vista de um atacante, o acesso a diferentes máquinas significa diferentes credenciais de nuvem potenciais para roubar ou diferente acesso à rede que poderia ser abusado para explorar outras máquinas.
Para mais informações, consulte as informações básicas:
Você pode enumerar os nós configurados em /computer/
, você geralmente encontrará o **Built-In Node
** (que é o nó que executa o Jenkins) e potencialmente mais:
É especialmente interessante comprometer o nó Built-In porque ele contém informações sensíveis do Jenkins.
Para indicar que você deseja executar o pipeline no nó Jenkins embutido, você pode especificar dentro do pipeline a seguinte configuração:
Exemplo completo
Pipeline em um agente específico, com um gatilho cron, com variáveis de ambiente de pipeline e estágio, carregando 2 variáveis em um passo e enviando um shell reverso:
Leitura Arbitrária de Arquivo para RCE
RCE
Pós Exploração
Metasploit
Jenkins Secrets
Você pode listar os segredos acessando /credentials/
se tiver permissões suficientes. Note que isso listará apenas os segredos dentro do arquivo credentials.xml
, mas arquivos de configuração de build também podem ter mais credenciais.
Se você pode ver a configuração de cada projeto, você também pode ver lá os nomes das credenciais (segredos) sendo usados para acessar o repositório e outras credenciais do projeto.
From Groovy
From disk
Esses arquivos são necessários para decriptar segredos do Jenkins:
secrets/master.key
secrets/hudson.util.Secret
Tais segredos geralmente podem ser encontrados em:
credentials.xml
jobs/.../build.xml
jobs/.../config.xml
Aqui está uma regex para encontrá-los:
Decryptar segredos do Jenkins offline
Se você tiver despejado as senhas necessárias para descriptografar os segredos, use este script para descriptografar esses segredos.
Descriptografar segredos do Jenkins a partir do Groovy
Criar novo usuário administrador
Acesse o arquivo Jenkins config.xml em
/var/lib/jenkins/config.xml
ouC:\Program Files (x86)\Jenkins\
Procure a palavra
<useSecurity>true</useSecurity>
e mude a palavratrue
parafalse
.sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
Reinicie o servidor Jenkins:
service jenkins restart
Agora vá para o portal Jenkins novamente e Jenkins não pedirá credenciais desta vez. Navegue até "Gerenciar Jenkins" para definir a senha do administrador novamente.
Ative a segurança novamente mudando as configurações para
<useSecurity>true</useSecurity>
e reinicie o Jenkins novamente.
Referências
Last updated