Escrito por Cole Herzog
Ofuscações e você
Application security é um conhecido conhecido agora. Todos sabem que precisam disso e os invasores sabem como derrotar as proteções básicas; enviar um aplicativo desprotegido simplesmente não é uma opção. Todas as proteções fortes têm duas partes: prevenção de análise estática e detecção de ataque dinâmico. A análise estática é uma ferramenta poderosa que fornece aos invasores uma visão exclusiva dos detalhes de implementação específicos da aplicação. Ele expõe as partes mais vulneráveis de um aplicativo, ajudando a acelerar um ataque ou roubar IP comercial valioso. Código-fonte, bem como dados, ofuscação é uma parte importante de qualquer proteção de análise estática. Aqui estão algumas maneiras pelas quais o código e os dados podem ser transformados para desacelerar atores mal-intencionados. Quanto mais eles têm que trabalhar, mais safecomo o nosso mundo pode ser.
Privatize sua proteção
Embora os aplicativos não devam ser enviados sem alguma forma de ofuscação, nem todas as ofuscações são criadas iguais. Dois componentes cruciais para qualquer ofuscação forte são o IP privado e a randomização. Os ofuscadores de código aberto disponíveis atualmente podem ser tão úteis para os invasores quanto para os desenvolvedores de aplicativos. O nível de proteção fornecido por esses ofuscadores de código aberto não é poderoso o suficiente para proteger aplicativos de qualidade empresarial de maneira confiável. Ofuscações impactantes precisam transformar o código-fonte em algo ilegível para humanos e irreversível por ferramentas de ataque automatizadas. As técnicas de ofuscação disponíveis publicamente funcionam como sua própria Pedra de Roseta para derrotá-los. O uso de técnicas de ofuscação personalizadas e não acessíveis ao público impede que Timmy Turner reverta a ofuscação de um aplicativo usando suas Fadas de IA Generativa. Combine esses algoritmos privados com a aleatoriedade inerente para garantir que nenhum ser humano, ou LLM, possa desembaraçar o fio.
PRNG contra-ataca
Os invasores podem obter muitas informações comparando diferentes releases do mesmo aplicativo. Alterar as ofuscações entre as versões do aplicativo é uma necessidade absoluta. A maioria dos mecanismos de pseudo-randomização usa uma semente para forçar a previsibilidade enquanto mantém a aleatoriedade inerente, e os ofuscamentos não são diferentes. Simplesmente aumentar ou diminuir um valor inicial terá um impacto dramático nos ofuscamentos aplicados a um aplicativo de entrada. Isso proporciona reprodutibilidade quando necessário, mas força os invasores a recomeçarem ao reverter um aplicativo após uma nova versão ser lançada. released. É como se o invasor limpasse metade da calçada, fizesse uma pausa para tomar um chocolate quente e voltasse para a neve fresca. A segurança forte concentra-se em desperdiçar um engenharia reversa tempo, e uma paisagem em constante mudança é uma das melhores maneiras de desperdiçar seu tempo.
Ofuscação Ofuscação Ofuscação
Conceitualmente, a ofuscação é o oposto da otimização. Assim como os compiladores costumam ter várias passagens de otimização, temos várias passagens de ofuscação. Isso significa que aplicamos ofuscação às ofuscações que acabamos de adicionar. O resultado é incrivelmente difícil de ler.
Coisas como uma simples instrução `add` ou `mov` podem rapidamente se tornar cinquenta ou centenas de instruções. Ofusque os pares `adrp add` corretamente pode dizimar a capacidade de uma ferramenta automatizada (como ghidra ou IDA) de resolver o fluxo de controle do programa. Ofuscações aparentemente menores podem tornar quase impossível para um invasor encontrar o início, o fim ou o meio da chamada de função `acceptUserCredentials`. Centenas de combinações e ofuscações variadas deixam possíveis invasores tentando descobrir como o código é executado com êxito.
Bop, torça, configure
Nem todo método ou chamada de função é sensível em um aplicativo, e algumas chamadas de método ou função podem ser altamente sensíveis ao desempenho. Embora a aplicação uniforme de ofuscação em todo o aplicativo ainda seja significativamente melhor do que nada, essa estratégia pode ter um impacto considerável no desempenho do tempo de execução. Oferecer aos engenheiros de segurança a capacidade de ofuscar fortemente chamadas confidenciais, ao mesmo tempo que ofusca levemente chamadas com uso intensivo de desempenho, faz parte do fornecimento de uma ferramenta de proteção de classe mundial. Quaisquer proteções dinâmicas (Guardas) injetadas no aplicativo exigem tanta ofuscação quanto o código-fonte subjacente exige. Aplicar as mesmas técnicas de ofuscação de alta segurança a esses guardas ativos ajuda a mantê-los protegidos e em funcionamento e retarda os esforços dos invasores para identificá-los e removê-los. A configurabilidade é crucial para qualquer organização centrada na segurança, e as ferramentas de proteção precisam mudar tão rapidamente quanto a direção da empresa. Conforme mencionado anteriormente, alguns ofuscamentos são construídos de forma diferente. Aqui estão alguns conceitos que qualquer mecanismo de ofuscação sério fornece e como ele pode impedir a entrada de tráfego aéreo não aprovado.
Fluxo de controle computado
Os invasores podem obter bastante conhecimento sobre um aplicativo apenas observando o fluxo de chamadas de função em todo o aplicativo. Para combater isso, nossos ofuscamentos usam algo chamado Fluxo de Controle Computado. O Computed Control Flow impede que os descompiladores conectem chamadas de função e referências de rótulo ao ponto de entrada principal dos aplicativos. É uma parte crítica de qualquer proteção de classe mundial. Quando um descompilador analisa um binário, ver como uma função chama outra função costuma ser trivial. Tomemos, por exemplo, instruções como: `b.eq 0x10055bc42` e `bl 0x100abcdef`. Um descompilador sabe exatamente o que existe nesses locais de memória virtual. No caso das duas instruções anteriores, são rótulos dentro de uma função ou a própria chamada de função. Qualquer descompilador que se preze renderizará uma bela teia de chamadas de função entrelaçadas, mostrando um caminho claro de execução em todo o aplicativo. Combine isso com outros truques básicos, como ver onde no assembly uma mensagem de “login bem-sucedido” é usada, e torna-se trivial para um invasor identificar código explorável. Fluxo de controle computado é um conjunto de operações matemáticas injetadas antes de chamadas óbvias de fluxo de controle. Essas operações matemáticas impedem que um descompilador saiba o endereço virtual relativo exato para o qual está sendo saltado, destruindo sua capacidade de gerar um gráfico de fluxo de controle.
Controle de nivelamento de fluxo
O Computed Control Flow já é um terror para os descompiladores; com certeza seria uma pena se piorássemos as coisas. Outra estratégia para inviabilizar o fluxo de controle lógico é chamada de nivelamento do fluxo de controle. Temos várias formas de CFF, mas uma recentemente adicionada (chamada The Nexus) dá vida nova a essa técnica de ofuscação crítica. Todos nós já escrevemos um jogo de xadrez em `main` antes, mas que tal escrever uma aplicação inteira em nível de produção em uma única instrução switch auto-referenciada? O Nexus faz exatamente isso, ao mesmo tempo que prioriza o desempenho do tempo de execução. Há uma infinidade de informações sobre o CFF, sua importância e como funciona. É impossível subestimar o quão difícil essa técnica de ofuscação torna a vida dos invasores, e nenhum aplicativo deve sair do teste sem ela.
C-hop-up
Nenhum conjunto de facas de aço inoxidável estaria completo sem uma tesoura de aço inoxidável correspondente, e o Chopup complementa os ofuscamentos do fluxo de controle da mesma maneira. Os formatos de arquivo binário geralmente são compactados para economizar espaço em disco. Isso significa que a maioria das chamadas de função relacionadas são bem próximas umas das outras. Como resultado, um binário desmontado tende a agrupar funções relacionadas e quase sempre tem funções como um bloco contíguo no binário. Isso é muito fácil de ler e realmente nos atrapalha. Chopup muda isso. Não há nenhuma restrição técnica em um binário que exija que as chamadas de função sejam contíguas na memória, e uma boa tesoura (com um pouco de cola flexível) pode deixar um binário funcionando como esperado, mas forçar os invasores a pular para todos os cantos do binário em busca de soluções lógicas. controle de fluxo.
mgDaea e reparo
Embora ofuscar o fluxo de código em si seja uma camada crucial de proteção, ofuscar os dados subjacentes do aplicativo é igualmente necessário. Danos e Reparos são o Mal Caótico e o Bem Legal das proteções de análise estática e quase sempre andam de mãos dadas. Danificar um dado ou mesmo, em alguns casos, um trecho de código e, em seguida, repará-lo antes de ser lido ou executado torna a análise estática efetivamente impossível. O dano transforma os dados especificados no que parece ser memória de lixo. Quando esses mesmos dados são expostos a uma chamada de reparo, eles são revertidos para sua forma original, muitas vezes antes de serem usados. Esses dados podem ser danificados novamente após saírem do escopo e não serão usados até a próxima vez que a função for chamada. Essa chave de API pode ser “1#&at0d$*nd@@z” no binário para começar, mas tenha certeza, ela será corrigida antes de ser usada.
Renomeação de símbolos
Mesmo com ofuscação de código-fonte e ofuscação de dados, ainda existem nomes de símbolos de código-fonte restantes em um binário compilado. Por exemplo, um artefato de símbolo para um nome de função como “acceptContinuousPayment” pode facilmente fornecer um link direto para a implementação dessa função. Uma vez encontrado, é fácil alterar a montagem e acessar recursos premium sem pagar. A renomeação abrangente de símbolos esconde os artefatos restantes e não deixa nada para os invasores trabalharem. A remoção de quaisquer dicas ou pistas sobre funcionalidades confidenciais em um binário protegido pode forçar os invasores a desistir completamente da análise estática.
O Fim
Estes são apenas exemplos de como são as práticas e metodologias de ofuscação fortes, e não é de forma alguma uma lista exaustiva. Deixar um aplicativo desprotegido em liberdade dá a qualquer pessoa visibilidade completa do IP exclusivo e fornece a qualquer invasor uma janela livre de névoa para a lógica de negócios. Com a ascensão meteórica da IA generativa e dos copilotos de código-fonte no mainstream, tornou-se infinitamente mais fácil para as pessoas escreverem código e para algumas pessoas reverterem o código. Um compromisso de toda a organização para implementar soluções de segurança fortes é o único caminho viável num ambiente tão acelerado. Não deixe o trabalho duro do seu desenvolvedor sair de casa sem ele.
Leia a opinião da IDC sobre a importância de ofuscação e anti-adulteração como parte do seu DevSecOps prática.
Você está pronto para escalar sua empresa?
Explore
O que há de novo no mundo da Digital.ai
Como funciona o dobrador de carta de canal Continuous Testing Promove a colaboração entre desenvolvimento e segurança: a abordagem moderna para o desenvolvimento seguro
Descubra como continuous testing e app sec promovem um SDLC colaborativo, criando um labirinto complexo para invasores, ao mesmo tempo em que capacitam equipes e reduzem custos.
Preocupações de segurança: como garantir a segurança do código gerado por IA
IA segura e código escrito por humanos com Digital.ai Application Security, perfeitamente integrado aos pipelines de CI/CD, oferecendo mecanismos de proteção robustos.
Protegendo aplicativos iOS pós-DMA: etapas rápidas para proteção empresarial
Explore as implicações da Lei dos Mercados Digitais para consumidores e empresas de iPhone que desenvolvem aplicativos. Aprenda como Digital.ai Segurança de aplicativos safeprotege contra ameaças potenciais.