Ataques maliciosos têm se lançado consistentemente em pontos fracos da cadeia de abastecimento. Como todos os ataques, estes irão evoluir para formas mais avançadas. O desenvolvimento de software, com várias fases que podem ser colocadas em risco, é particularmente vulnerável.
O agora infame caso Orion Solar Winds causou muito barulho tanto na comunidade de cibersegurança quanto na esfera pública, enquanto a atenção aos ataques à cadeia de suprimentos em todo o mundo também aumentou. Os ataques em si não são novos. Na verdade, esses tipos de ameaças são predominantes há algum tempo e, como normalmente acontece, eles evoluem naturalmente para formas mais avançadas. No artigo a seguir, discutimos exemplos anteriores de tais ataques e mergulhamos nos próximos cenários possíveis.
Onde estão os elos fracos?
Primeiro, estabelecemos uma definição concreta para uma cadeia de suprimentos. A definição genérica é “um processo de obtenção de um produto para o cliente”. Como estamos no mundo da informática, o produto aqui é software desenvolvido. Assim, primeiro nos concentramos no próprio processo de desenvolvimento de software.
Os desenvolvedores de software, independentemente da metodologia que usam, devem dividir projetos complexos em tarefas mais simples. Isso ocorre para que essas tarefas possam ser definidas e atribuídas a desenvolvedores específicos dentro do software de rastreamento de problemas preferido. Em seguida, o desenvolvedor escreverá um código que será testado e enviará as alterações para o software de gerenciamento de código fonte (source code management ou SCM).
Figura 1. Esboço do processo de desenvolvimento
O código será processado por um pipeline de integração contínua e entrega contínua (CI/CD) que executará tarefas específicas para realizar compilações, testes ou a implantação final da escolha do projeto.
Cada etapa dentro de nosso processo de cadeia de abastecimento definido tem seus próprios riscos e impactos de segurança. Por exemplo, algumas violações de segurança podem começar com usuários mal-intencionados de software de rastreamento de problemas. Esse usuário pode ser um insider furioso que tira proveito de informações seguras, como também pode ser alguém que usa a exploração de vulnerabilidade. Esses cenários podem acontecer, mas o impacto provavelmente será baixo, pois há muitas outras etapas na cadeia. As outras partes da cadeia de suprimentos provavelmente estarão sujeitas a tarefas maliciosas. Portanto, não perderemos muito tempo neste cenário, com uma exceção — autenticação.
Como a força de toda a cadeia de suprimentos é definida por sua parte mais fraca, ignorar as práticas recomendadas de segurança (como reutilização de senha ou falta de mecanismos de autenticação adequados) significa que o agente malicioso pode obter acesso a sistemas com maior impacto na exposição.
Desenvolvedores e SCM
Outra parte integrante da cadeia é o desenvolvedor, uma pessoa necessária para escrever o código. É importante considerar o lado humano das coisas como uma fraqueza e um possível risco à segurança. Não estamos propondo substituir o desenvolvedor por máquinas, mas sim educá-los sobre os riscos que podem enfrentar.
Recentemente, vimos agentes de ameaças visando pesquisadores de vulnerabilidade. De uma perspectiva técnica, o fato interessante é que essa ameaça estava escondida dentro de um arquivo de projeto do Visual Studio — especificamente dentro do evento de pré-criação — e gerou uma payload controlada pelo PowerShell. Existem dois resultados de conexão notáveis a partir desse cenário. O primeiro é o nível de confiança entre “pares” e o segundo (que é mais aplicável a desenvolvedores) é a maior adoção do código-fonte e integrações de projetos de terceiros. Deve-se ter cuidado com o código-fonte e quais projetos eles integram. Isso requer a verificação da origem do código, software, plug-ins ou contêineres usados. Já abordamos os problemas em um de nossos artigos anteriores sobre plataformas de codificação on-line.
O incorporador também tem acesso ao próximo trecho da rede, o SCM. Isso envolve credenciais e, como o processo de inserir credenciais repetidamente com acesso único é frustrante, elas são armazenadas. Junto com o armazenamento de credenciais, há o risco de vazamentos de credenciais e o impacto é maior quando elas são armazenadas em formato não criptografado.
Podemos ver um padrão comum na comunidade DevOps: os desenvolvedores armazenam credenciais em formato não criptografado (por exemplo, arquivos de configuração baseados em texto ou variáveis ambientais) e isso inclui tokens de serviço, nomes de usuário e endereços de e-mail.
Figura 2. Um exemplo de armazenamento de credenciais e tokens em texto simples dentro de ambientes “seguros”
Embora pareça que essas questões de segurança sejam excessivas, o clichê de que a corrente é tão segura quanto sua parte mais fraca é verdadeira. Portanto, as precauções que reduzem o risco (por exemplo, usar cofres de senha) devem ser levadas em consideração, pelo menos.
Figura 3. Um exemplo de uso de credenciais de texto simples codificadas dentro do código-fonte
Em essência, os desenvolvedores não devem enviar credenciais codificadas para o SCM. Por exemplo, ao usar infraestrutura como código (Infrastructure as a Code ou IaC), eles devem pensar no armazenamento de credenciais em geral.
Pipeline de CI / CD
A próxima parte da cadeia é o pipeline de CI/CD. Existe uma forte competição entre os fornecedores de software. Nomes familiares incluem Jenkins, GitLab, TeamCity, Azure DevOps e outros.
O pipeline dentro do software CI/CD pode ser dividido no seguinte:
Figura 4. Pipeline de CI/CD
Acesso ao sistema
Do ponto de vista da segurança, o acesso a tais sistemas deve ser limitado e não acessível a todos. Deve estar oculto na rede corporativa, acessível apenas para usuários com funções especificadas e, portanto, direitos de acesso especiais. Mesmo a simples exposição à Internet é um risco à segurança, pois uma vulnerabilidade pode existir e ser ativamente explorada por agentes de ameaças, como já vimos antes.
Configuração do sistema
Outra possível fonte de risco de segurança e problemas relacionados é a configuração incorreta. Certas configurações fazem sentido para ambientes específicos. Por exemplo, uma empresa requer que vários usuários tenham acesso ao sistema, mas todos têm funções diferentes. Nessa situação, a segurança baseada em função deve ser configurada. No entanto, existem armadilhas envolvidas nessas configurações, como descrevemos anteriormente no caso do Jenkins. Com o aumento da complexidade do software e das opções de configuração, o teste de problemas comuns de configuração incorreta de software é altamente encorajado.
Obtendo o Código Fonte
Podemos distinguir dois padrões aqui:
O SCM é integrado ao CI/CD, como no caso do servidor Azure DevOps
O SCM está sendo executado em ambientes diferentes. Dessa forma, os tokens de acesso ou credenciais devem ser armazenados dentro do sistema.
A maneira como o software armazena as credenciais do código-fonte é crucial, pois sua exposição pode levar a modificações maliciosas no código-fonte. No entanto, é notável mencionar que vimos práticas inseguras usadas dentro do software CI/CD e descobrimos vulnerabilidades de armazenamento de credenciais não criptografadas em extensões de terceiros (como no caso dos plug-ins Jenkins).
Configuração do ambiente de construção
Os aspectos de segurança aqui estão obviamente relacionados às credenciais passadas. Existe o risco de passar credenciais não criptografadas e seu armazenamento nas formas de artefatos de construção. Essencialmente, alguns pré-requisitos de configuração contêm informações confidenciais que geralmente serão deixadas para trás após uma construção.
Construindo
Esta é a etapa de compilar o código-fonte real na forma binária de destino. Vimos ataques nesta fase no caso Solar Winds, bem como no caso CCleaner. Existem razões lógicas para um invasor atacar durante esta fase. Em primeiro lugar, por ser uma das últimas etapas da cadeia de abastecimento, isso significa que não haverá muita verificação depois. Em segundo lugar, os binários executáveis produzidos são normalmente assinados digitalmente todos os anos. Isso significa que qualquer modificação de código que ocorrerá após a assinatura do código não terá uma assinatura digital válida. O hash do binário não corresponderia e, como ele é criptografado por uma chave privada, não seria possível gerar um hash válido sem seu conhecimento. É por isso que o processo de construção é um alvo adequado para ataques à cadeia de suprimentos. No entanto, nem todos os softwares são enviados com uma assinatura digital.
Quando mencionamos a assinatura digital, temos que enfatizar a necessidade de manter a chave privada do certificado em segredo. A exposição dessa chave privada significaria que os invasores podem assinar digitalmente qualquer software que quiserem com esse certificado e, portanto, ele deve ser revogado.
Implantação ou entrega do produto
A última parte da cadeia que também podemos incluir no CI/CD é a implantação. Em primeiro lugar, o processo de implantação pode ser especificado dentro do software CI/CD e acionado após uma compilação ou teste bem-sucedido. Assim, as informações de arquitetura podem estar presentes aqui juntamente com as credenciais e outras informações sigilosas, enfatizando a necessidade de seu gerenciamento adequado.
A maneira mais fácil para um invasor é substituir todo o produto de software. A injeção de código malicioso também é usada e é adequada para certas aplicações (não assinados digitalmente). Como exemplo, podemos ver ataques de injeção de código em sites com tecnologia WordPress, onde trechos de código malicioso são inseridos como resultado de vulnerabilidade ou exploração de falha de segurança.
Uma injeção de código binário executável também é possível, mas é mais dependente do binário compilado e das habilidades de um invasor. Além disso, se o binário for assinado digitalmente, o ataque será facilmente descoberto e não será eficiente. Uma substituição binária simples é mais conveniente para os invasores. No entanto, invadir um servidor de entrega (servidores que permitem aos usuários fazer download de produtos de software reais) onde o binário está armazenado não é uma tarefa fácil e exigiria recursos significativos. Em vez disso, táticas como phishing, campanhas fraudulentas ou ataques de spoofing de DNS foram lançadas junto com o uso indevido de marcas de software conhecidas (até mesmo fornecedores de segurança) para entregar payloads maliciosos ou grayware.
Conclusão
Este o blog post simplesmente descreve as questões básicas relacionadas à segurança da cadeia de suprimentos. Os problemas desses tipos de ataques são muito complexos para serem abordados em apenas uma postagem. Essa é uma questão particularmente urgente porque as empresas devem executar a maior parte de seu payload em nuvem até o final de 2021, conforme discutimos em nossas previsões anuais. Isso significa que, em resposta à crise de saúde, muitas organizações estão adotando novos softwares aleatoriamente, sem compreender totalmente o escopo completo das questões de segurança.
Para saber mais sobre ataques documentados à cadeia de suprimentos, visite esta página do GitHub.