Jenkins Security
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
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.
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.
Nas informações básicas, você pode verificar todas as maneiras de fazer login no Jenkins:
Você poderá encontrar instâncias do Jenkins que permitem que você crie uma conta e faça login nela. Simples assim.
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 teste do Github/Bitbucket). Dica de aqui.
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.
Use this python script ou this powershell script.
Muitas organizações combinam sistemas de gerenciamento de controle de versão (SCM) baseados em SaaS como GitHub ou GitLab com uma solução 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 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 CI interno.
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 da permissão 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:
Se você acessou o Jenkins, pode listar outros usuários registrados em http://127.0.0.1:8080/asynchPeople/
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.
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.
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.
Criar/Modificar um projeto é uma maneira de obter RCE sobre o servidor Jenkins:
Você também pode obter RCE executando um script Groovy, que pode ser mais discreto do que criar um novo projeto:
Você também pode obter RCE criando/modificando um pipeline:
Para explorar pipelines, você ainda precisa ter acesso ao Jenkins.
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.
Na seção anterior de RCE, já foi indicada uma técnica para obter RCE modificando um pipeline.
É 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 poderia sempre verificar todas as configurações do pipeline/Jenkinsfiles:
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.
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.
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, verifique 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ó Built-In do Jenkins, você pode especificar dentro do pipeline a seguinte configuração:
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:
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.
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:
Se você tiver despejado as senhas necessárias para descriptografar os segredos, use este script para descriptografar esses segredos.
Acesse o arquivo Jenkins config.xml em /var/lib/jenkins/config.xml
ou C:\Program Files (x86)\Jenkins\
Procure a palavra <useSecurity>true</useSecurity>
e mude a palavra true
para false
.
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 alterando as configurações para <useSecurity>true</useSecurity>
e reinicie o Jenkins novamente.
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)