Arquivo

Arquivo da Categoria ‘Segurança’

Hack New Year: MD5 Chain com Rainbow Table

2, janeiro, 2010 11 comentários

Antes de qualquer coisa, gostaria de desejar a todos um feliz ano novo cheio de felicidades e que seus objetivos sejam edificados em 2010.

Criptografia com certeza é um assunto de interesse de muitos, porém por ser uma área tão extensa e de pré-requisitos (álgebra, geometria, trigonometria, teoria dos números, etc) que realmente não agradam alguns muitas vezes não são estudadas como hobby.

A criptoanálise é o ramo da ciência que estuda métodos de criptografia, capacitando ao profissional fazer a análise de um algoritmo criptográfico quanto a sua complexidade, podendo definir um algoritmo como forte (de difícil quebra) ou fraco (de fácil quebra).

Como dito, para se estudar criptografia, geralmente tem-se a necessidade de um forte embasamento matemático. Para se ter idéia, algumas linhas da matemática pura estudados a 20 anos atrás são chave fundamental para os melhores algoritmos de criptografia da atualidade.

Alguns ramos de estudo de criptografia não necessitam de um embasamento profundo em matemática. Um desses ramos é o Hash Chain, base para o tão conhecido Rainbow Table (vide Project RainbowCrack), que utiliza uma técnica chamada Time-memory Tradeoff (TMTO).

Em um ataque de força-bruta (brute-force) convencional a um algoritmo de hash, são gerados todas as possíveis senhas com seus respectivos hash’s, e então procura-se um determinado hash para tentar obter a senha original. Porém, levando em consideração uma senha composto das letras de a à z (26 letras) e uma senha de até 7 caracteres, temos o total de:
Formula

O maior problema não é calcular as senhas, e sim armazená-las, já que só para armazenar cada um dos 16 bytes do hash MD5 serão necessários mais que 124Gb de espaço. Se fosse até 8 (oito) caracteres esse valor iria mais que dobrar.

O Time-Memory Tradeoff tem por objetivo reduzir drasticamente a quantidade de memória utilizada em troca de um processamento um pouco maior, porém esse processamento poderia ser feito uma única vez e, dentro a tabela de hash bastaria apenas consultar.

Para se reduzir o tamanho do espaço armazenado, utiliza-se o chamado Hash Chain, que tem por finalidade armazenar uma palavra pertencente ao alfabeto e um hash não necessariamente equivalente a ela.

Iremos tomar como exemplo um alfabeto contendo as letras minúsculas de a à z. Com isto temos 26 letras em nosso alfabeto. Uma palavra é qualquer sequência de caracteres, todos pertencentes ao alfabeto dado e um dicionário é um conjunto de palavras.

O Hash Chain é formado da seguinte forma, dado uma palavra do dicionário, aplica-se uma função de hash H e em seguida aplica-se uma função R, tal que R resulte em uma palavra também pertencente ao dicionário. Faz-se essa operação uma determinada quantidade de vezes (aqui chamadas de iterações) e, ao final, armazena-se o hash resultante, por exemplo:

aaaaaa —H→ 281DAF40 —R→ sgfnyd —H→ 920ECF10

No exemplo acima fizemos apenas duas iterações com a palavra “aaaaaa”. Inicialmente aplicamos a função de hash e obtivemos o valor 281DAF40. Em seguida foi aplicação a função R resultando na palavra “sgfnyd” , pertencente ao dicionário. Por ultimo aplicou-se novamente a função de hash resultando no hash 920ECF10.

Dado um hash para consultar, verifica-se se ele esta contido na tabela de hash’s gerada. Caso ele seja encontrado, é provável que a partir da palavra inicial consiga-se obter a palavra equivalente ao hash. Por exemplo, se tivermos o hash 920ECF10, podemos encontrá-lo na tabela, sendo equivalente a palavra inicial aaaaaa, bastando apenas fazer as operações H e R varias vezes até encontramos a palavra que tenha o hash dado ou não encontrarmos (atingindo o máximo de iterações). Caso o hash procurado não esteja na tabela, aplica-se consecutivamente as funções R e H no hash fornecido, procurando novamente na tabela, fazendo assim com que o hash fornecido converja à um hash da tabela ou atinja o número máximo de iterações (caso não seja encontrado).

É importante ressaltar que a função R não pode ter qualquer aleatoriedade, ou seja, um valor de hash é sempre transformado na mesma palavra do dicionário. A diferença do Hash Chain puro para o Rainbow Table é que o segundo possui diversas funções R que transformam um hash qualquer em uma palavra do dicionário, tentando assim evitar colisões (dois hash resultarem na mesma palavra).

Para efeitos de ilustração escrevi um código como prova de conceito (p0c), que gera em tempo real um dicionário, faz diversas iterações e depois procura um dado hash. É importante deixar claro que esse código é somente demonstrativo, porém ele pode futuramente virar um projeto da Hack’n Roll. Algumas limitações dele é o dicionário ser fixo (letras de a à z), você tem que fornecer o tamanho da senha do hash (isso o torna completamente inútil sozinho em um ambiente real), terei que melhorar (e muito) a função que transforma o hash em uma palavra do dicionário, etc.

Quebra do hash da palavra hack

A ferramenta faz o que promete, porém algumas (muitas) vezes ele não encontra a palavra solicitada. Isso se dá porque o dicionário inicial é gerado aleatóriamente, para um melhor resultado, basta executar novamente com os mesmos parâmetros até ele encontrar a palavra solicitada:
Quebra do hash MD5 da palavra natal

Não recomendo tentar utilizar o md5-chain como ferramente de quebra de hash MD5. Ele foi escrito com o único propósito de explicar o conceito de hash chain, time-memory tradeoff e como funciona o projeto RainbowCrack. Este ultimo já possui diversas melhorias matemáticas além de ter instruções específicas para trabalhar com GPU (processadores de placas de vídeo).

No projeto RainbowCrack, a tabela palavra/hash é gerada e armazenada em arquivo, sempre fazendo algumas verificações. Dessa forma bastaria fazer as consultas necessárias e obter os resultados.

O código-fonte do md5-chain pode ser obtido aqui. Sinta-se livre para modificá-lo e estudá-lo à vontade. Um desafio seria reescrever a função makepass() que gera uma palavra a partir de um hash, cuja execução com um dicionário inicial de 2000 palavras e 2000 iterações de uma senha de 5 caracteres não gere muitas (ou nenhuma) repetição.

Bom estudo e feliz hack’n roll.

Referências:
http://en.wikipedia.org/wiki/Rainbow_table
http://en.wikipedia.org/wiki/Space-time_tradeoff
http://www.cs.sjsu.edu/faculty/stamp/RUA/TMTO.pdf
http://project-rainbowcrack.com/

Categories: Criptografia, Segurança Tags:

A Verdade sobre o Apagão

12, novembro, 2009 186 comentários

Eu? Como? Quando? onde? Por que? 18 anos? Na verdade eu tinha 23 anos. :-)

Ensinar a molecada a parar o metrô de SP pode, né ‘champion’!?

Agora é sério, você nasceu pra cagar merda pela boca. Pare de falar e subjugar as pessoas e faça algo de relevante antes de colocar a palavra pesquisador entre aspas. Cadê seus exploits? Cadê seus CVEs? Cadê a sua contribuição? Não me venha dizer que vender treinamento lixo e palestras lixo em eventos lixo é algo de bom, pois todos sabemos qual o seu principal objetivo ni$$o tudo.

Para quem não conhece nosso amigo, segue um recado da comunidade de segurança:

… e mais esse …

Uma dica pra ele de nosso grande herói He-man:

Happy Hack N’ Roll. :-)

Categories: Segurança Tags:

Análise do Virus TR/ATRAPS.Gen – Parte 1

12, abril, 2009 20 comentários

Hoje cheguei em casa umas 12h e notei que tinha uma mensagem no MSN com o seguinte:

Esta foto te miras padre!

http://img456.myspace-imagen.info/img456/my.php?id=MVC-IMAGEN41.jpeg

Então pensei: Ou a minha tia está aprendendo espanhol e esta querendo praticar comigo, ou ela esta com um vírus de MSN. Para tirar minhas dúvidas cliquei no link e, como de se esperar, o navegador abriu uma janela para eu efetuar download do arquivo MVC-IMAGEN41.jpeg.src. Então o salvei e comecei a fazer a análise dele.

Ao submeter para o VirusTotal, notei que dos 37 anti-virus com base de assinaturas registradas, somente 4 o detectaria como vírus. Para maiores detalhes da submissão do vírus acesse VirusTotal

Abri no PEiD para ver o que ele me falava do arquivo, e obtive a seguinte resposta:

figura01

Pelo PEiD foi possível notar que não existe nenhum tipo de compactação nem criptografia das sessões do binário. Então bastamos abrir o binário para uma análise direta.

Abri o binário no OllyDbg e logo no inicio vemos a seguinte chamada:
figura02

Inicialmente ele aloca memória na pilha e em seguida move uma constante para o registrador EAX e efetua uma chamada. Ao analisarmos a chamada temos o seguinte:

figura03

Nesta chamada é salvo o parâmetro que está em EAX no registrador EBX em seguida move-se o valor 0 (zero) para a posição [44064] que representa o TLS (Thread-Local Storage) do processo, utilizada para criar um mecanismo de IPC. Por padrão, às variáveis locais de uma função são únicas para cada thread que execute a função e as variáveis globais e estáticas (static) são compartilhadas por cada processo. Com TLS, utilizando um índice global, é possível prover um dado único para cada thread que o processo pode acessar.

Após zerar o TLS, o processo efetua uma chamada a API GetModuleHandleA[1] passando 0 (zero) como parâmetro. A API GetModuleHandleA() retorna o handle (ponteiro) para o módulo passado como parâmetro, o módulo no caso seria algum outro processo ou DLL carregado na mesma região de memória do processo atual. Como foi passado como parâmetro o valor 0 (zero) a API retornará o Handle do arquivo que criou o processo atual, no caso o nosso m4ware.

Em seguida o processo salva o resultado nos endereço DS:[4566C] e DS:[4406C], então para facilitar o trabalho colocamos um label (rótulo) nesses endereços.

figura04

Nesta sub-rotina, vemos um exemplo clássico de anti-debugger. Esse trick consiste é pegar o uptime da máquina em milissegundos (GetTrickCount[2]), em seguida efetuar uma pausa (Sleep) e pegar novamente o numero de milissegundos. Com isto verifica-se se as diferenças foram compatíveis. No exemplo, o malw4re pega o ms da máquina, da uma pause de 501ms e em seguida pega o ms novamente e então verifica se a diferença foi de 501ms. Então a sub-rotina retorna 1 (um) em EAX caso ocorra a diferença (debug detectado) ou 0 (zero) caso não tenha detectado. Após a verificação, o malw4are altera seu fluxo caso tenha sido detectado o debug, executando o salto condicional (endereço 00043616).

Não tenho detectado o debuger, o malw4are prossegue normalmente e em seguida executa a seguinte rotina passando o valor 6F (111 dec.) no registrador EAX:

figura05

No inicio temos o prelúdio normal de uma rotina (salva pilha e separa nova pilha). Em seguida temos a alocação de uma região da pilha (variáveis locais). Salva-se o valor de EAX (parâmetro) em EBX e executa um Sleep de 50ms. Após a pausa, o m4lware soma Trick do sistema e com o parâmetro passado e executa um salto incondicional para o meio de loop (endereço 000434D4). O loop executa diversas leituras de mensagens do sistemas. A estrutura de resposta da mensagem fica armazenada na pilha no endereço SS:[EBP-1C], então o processo verifica pela mensagem de ID 12h para então sair[3].

Ao sair desta rotina, o m4lware passa para a seguinte rotina:

figura06

Inicialmente temos o prelúdio com a alocação e inicialização (com zeros) das variáveis locais da sub-rotina. É possível notar diversas chamadas a API LoadLibraryA[4], que é responsável por carregar uma determinada biblioteca (DLL) dinamicamente, ou seja, sem estar no IMPORT_TABLE do binário. Porém, antes de cada chamada, temos a chamada a três sub-rotinas do binário. Analisando superficialmente, é possível notar que a primeira rotina carrega uma mensagem codificada, a segunda decodifica a mensagem e a terceira verifica se teve sucesso ou não. Com isto, é possível verificar que as chamadas as APIs LoadLibraryA() importam as bibliotecas kernel32.dll, advapi32.dll e ntdll.dll respectivamente. Em seguira é feito uma chamada a API GetProcAddress, que é responsável por, dado um handle de uma biblioteca (retorno da função LoadLibrary()) e um nome de API, retorna um ponteiro para a rotina da API. A chamada à GetProcAddress() busca e retorna o endereço da própria API GetProcessAddress em Kernel32.dll, armazenando seu retorno em DS:[ESI].

Após a obtenção do endereço de GetProceAddres em DS:[ESI], a rotina efetua diversas rotinas como as seguintes:

figura07

Com isto, o m4lware carrega as APIs RegCloseKey, RegQueryValueExA, RegOpenKeyA, EnumResourceNamesA, GetModuleHandleA, GetComputerNameA, GetUserNameA, GetFileAttributesA, FreeLibrary, FreeResource, ExitProcess, SizeofResource, LoadResource, LockResource, FindResourceA, SetThreadContext, TerminateProcess, ZwUnmapViewOfSection, VirtualAllocEx, WriteProcessMemory, CreateProcessA, GetThreadContext, ReadProcessMemory, SetThreadContext, ResumeThread e VirtualProtectEx, não necessariamente nesta ordem.

No final, esta rotina libera o handle das biblitecas kernel32.dll, advapi.dll e ntdll.dll carregados no inicio.

Bem, esta foi a primeira parte da análise do m4lware TR/ATRAPS.Gen, até então não encontramos nada de muito complicado nem ameaçador. Nos post futuros continuarei com a análise e talvez tenha algo de mais interessante.

Referências:
[1] GetModuleHandle Function: http://msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx
[2] Thread-Local Storage: http://msdn.microsoft.com/en-us/library/ms686749.aspx
[3] MSG Structure: http://msdn.microsoft.com/en-us/library/ms644958(VS.85).aspx
[4] LoadLibrary Function: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx

Categories: Análise de Binário, Malwares Tags:

Vacina Tiny.H

21, março, 2009 4 comentários

A arte da engenharia reversa realmente é tão fantastica quanto ampla. Muitas pessoas só conhecem engenharia reversa como o método utilizado para criar cracks, keygens entre outras ferramentas do gênero. Porém, a engenharia reversa é utilizada amplamente para migração de código entre plataformas (geralmente drivers para hardware sem documentação), análise de vulnerabilidades em ferramentas de código fechado e para análise de malwares para criação de vacina.

Das criações de vacinas, pude fazer minha primeira vacina para um virus denominado TINY.H que estava disseminado nos laboratórios da faculdade. Ele se auto-copiava para dispositivos removíveis (pen-drivers), criando dois arquivos executáveis e um autorun, todos com permissões ocultas e de arquivos de sistema.

O problema é que, como o usuário disponível não tinha permissão para nada, não era permitido matar os processos do virus e, consequentemente, apagar os arquivos do pen-drive.

Para solucionar o problema, desenvolvi uma pseudo vacina em VBS que remove os processos e limpa o pen-driver, segue algumas rotinas necessárias. Basicamente foram utilizados dois objetos: o FileSystemObject e o Windows Management Instrumentation (WMI) como segue:

1
2
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Tendo os objetos no escopo global, criei a seguinte rotina que remove as permissões de um dado arquivo:

1
2
3
4
5
6
7
8
9
10
11
'----------------------------------------------------------------------
' Esta função restaura as permissões dos arquivos de infecção para a
' NORMAL, pois os mesmo ficam com as permições SYSTEM, HIDDEN e ARCHIVE
'----------------------------------------------------------------------
Const FILE_ATTRIBUTE_NORMAL   = 128
 
sub RemovePermicoes(cArquivo)
    Wscript.Echo "  > " & cArquivo
    Set ObjFile = objFSO.GetFile(cArquivo)
    objFile.Attributes = FILE_ATTRIBUTE_NORMAL
end sub

Juntamente com ela, criei a seguinte função responsável pela remoção de um dado arquivo:

1
2
3
4
5
6
7
8
9
10
11
12
'----------------------------------------------------------------
' Esta função remove um arquivo ( no caso virótico ) passado como
' parametro
'----------------------------------------------------------------
sub RemoveArquivo(cArquivo)
	objFSO.DeleteFile(cArquivo)
	if objFSO.FileExists(cArquivo) then
	    Wscript.Echo "  > Arquivo [" & cArquivo & "] NÃO removido"
    else
	    Wscript.Echo "  > Arquivo [" & cArquivo & "] removido"
	end if
end sub

Antes de remover as permissões e apagar o ‘dito cujo’, foi necessário remover todos os processos com origem no arquivo, para isto escrevi a seguinte função:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'----------------------------------------------------------------------
' Esta função é responsável por remover os processos relacionados aos
' arquivos que identificam os virus
'----------------------------------------------------------------------
sub RemoveProcessos(cCaminho)
    Wscript.Echo "  > Caminho: " & cCaminho
    Set colProcessList = objWMIService.ExecQuery ("SELECT * FROM Win32_Process")
    For Each objProcess in colProcessList
        if objProcess.ExecutablePath = cCaminho then
            objProcess.Terminate()
            Wscript.Echo "    > PID: " & objProcess.ProcessId & " morto"
        end if
    next
end sub

Estas três funções podem ser reutilizadas em quaisquer vacinas que precise destas funcionalidades. Agora iremos partir para as tarefas específicas do virus TINY.H.

Primeiro precisamos identificar a presença do virus. Para isto peguei o nome dos arquivos que ele gera, chamados autorun.inf, explorer.exe e fooool.exe. Com isto, escrevi a seguinte função que verifica se um determinado dispositivo (H:, i:, etc) esta infectado:

1
2
3
4
5
6
7
8
9
10
'---------------------------------------------------------------------
' Verifica a possivel infecção em um dispositivo, tendo como parametro
' a letra do dispositivo e verificando através da existencia dos
' arquivos deixados pela infecção
'---------------------------------------------------------------------
function DispositivoInfectado(cDispositivo)
    DispositivoInfectado = objFSO.FileExists(cDispositivo + "\autorun.inf") AND _
                           objFSO.FileExists(cDispositivo + "\explorer.exe") AND _
                           objFSO.FileExists(cDispositivo + "\fooool.exe")
end function

Sabendo que um determinado dispositivo esta infectado, basta utilizar as rotinas já vistas para restaurar as permissões dos arquivos (remover o SYSTEM, HIDDEN e ARCHIVE), matar os respectivos processos e remover os arquivos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'------------------------------------------------
' Função responsável pelo processo de desinfecção
'------------------------------------------------
function Desinfecta(cDispositivo)
    Wscript.Echo "----------------------------------"
    Wscript.Echo "======= Aplicando Recovery ======="
    Wscript.Echo "----------------------------------"
 
    Wscript.Echo "> Restaurando Permições para Original"
    RemovePermicoes cDispositivo & "\autorun.inf"
    RemovePermicoes cDispositivo & "\explorer.exe"
    RemovePermicoes cDispositivo & "\fooool.exe"
    Wscript.Echo ""
 
    Wscript.Echo "> Finalizando Processos Dependentes"    
    RemoveProcessos cDispositivo + "\explorer.exe"
    RemoveProcessos cDispositivo + "\fooool.exe"
    Wscript.Echo ""
 
    Wscript.Echo "> Apagando Arquivos"    
    RemoveArquivo cDispositivo + "\explorer.exe"
    RemoveArquivo cDispositivo + "\fooool.exe"
    Wscript.Echo ""
 
end function

E para nossa (pseudo-)vacina esta quase completa basta varrer todos os dispositivoes removíveis a procura de algum infectado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'-------------------------------------------------------------
' Busca todos os dispositivos removiveis a procura da infeccao
'-------------------------------------------------------------
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = " & REMOVABLE_DRIVER & "")
 
 
Wscript.Echo "----------------------------------"
Wscript.Echo "====== Verificando Infecção ======"
Wscript.Echo "----------------------------------"
 
 
boolInfected = False
For Each objDisk in colDisks
 
    if objDisk.DeviceID  "A:" then ' Não vale disquete :P

        '----------------------------------------------
        ' Verifica a existencia da infeccao nos drivers
        '----------------------------------------------
        if DispositivoInfectado(objDisk.DeviceID) then
 
            Wscript.Echo "> Possível infecção TINY/H em (" + objDisk.DeviceID + ")"
            Wscript.Echo "  > " + objDisk.DeviceID + "\autorun.inf"
            Wscript.Echo "  > " + objDisk.DeviceID + "\explorer.exe"
            Wscript.Echo "  > " + objDisk.DeviceID + "\fooool.exe"
            Wscript.Echo ""
 
            Desinfecta objDisk.DeviceID
            boolInfected = True
        end if
    end if
Next

Bem. Isto foi só um básico de escrita de vacinas contra malwares. O código completo esta disponível para download aqui, porém o mais interessante seria disponibilizar minha análise (pra quem gosta de assembly). Ela esta um pouco bagunçada, portanto se tiver um tempinho extra irei organizar e posta a análise de meu primeira malware.

Maycon Maia Vitali ( 0ut0fBound )

http://maycon.hacknroll.com

Hack’n Roll

Categories: Análise de Binário, Segurança Tags:

Serial Fishing

3, março, 2009 13 comentários

Estava procurando rever algumas coisas de engenharia reversa e fui ‘brincar’ com serial Fishing. Serial fishing é possível quando a aplicação, ao tentar verificar se o serial digitado foi fornecido corretamente, gera o serial original para fazer uma comparação. Vamos ver como podemos tirar proveito disto.

Como o serial gerado pela aplicação esta residente na memória, basta abrir o processo e pegar ele bonitinho na memória. A parte mais emocionante é encontrar o serial na memória (isto se ele estiver lá). Para fins de uso pessoal estudo, achando tendo o serial na memória já basta, porém como bons nerds atoas que somos, nós escrevemos um código que pegue e exiba o serial na tela.

O programa que estava testar é o jogo Xadrez Master na versão 5.8.6.0, ao abri-lo no OllyDbg e digitar qualquer nome e serial, é exibida uma mensagem informando que o serial está inválida. Sem fechar a janela, voltei para o Olly, dei pause no processo e então pude analisar o seguinte na memória:

CPU Dump:
0012EA48  |00F2F1A8  ASCII "Maycon Maia Vitali (0ut0fBound)"
0012EA4C  |00F36868  ASCII "XAD-BXLT4-TLKXJ"
0012EA50  |00F1C8A4  ASCII "XAD"
0012EA54  |00F2F18C  ASCII "AABBCCDDEEFF"
0012EA58  |00EDCB64  ASCII "AAB"
0012EA5C  |00F1CEAC  ASCII "Maycon Maia Vitali (0ut0fBound)"
0012EA60  |00F2F170  ASCII "XAD-BXLT4-TLKXJ"
0012EA64  |00F1CE90  ASCII "AABBCCDDEEFF"
0012EA68  |00ED1D64  ASCII "AABBCCDDEEFF"
0012EA6C  |00ED1D80  ASCII "AABBCCDDEEFF"
0012EA70  |00F1CE74  ASCII "AABBCCDDEEFF"
0012EA74  |00ED1D0C  ASCII "Maycon Maia Vitali (0ut0fBound)"
0012EA78  |00ED1D38  ASCII "Maycon Maia Vitali (0ut0fBound)"

Estes dados foram obtidos da pilha, e podemos notar o serial XAD-BXLT4-TLKXJ para o nome “Maycon Maia Vitali (0ut0fBound)” em diversos endereços diferentes. Vamos pegar só um exemplo:

0012EA48  |00F2F1A8  ASCII "Maycon Maia Vitali (0ut0fBound)"
0012EA4C  |00F36868  ASCII "XAD-BXLT4-TLKXJ"

Neste caso, nos endereços 0012EA48 e 0012EA4C temos respectivamente os endereços de memória onde estão o nome e serial válidos. Portanto nosso “Serial Fisher” deve obter antes os endereços das strings na memória para depois le-las em sí.

Sem muitas firulas, segue um código-rápido que fiz para fazer Serial Fishing desse software. Lembrando que é necessário digitar um serial qualquer e pressionar o botão de registrar e, sem fechar a caixa da mensagem informando serial inválido, rodar o fisher(pescador):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
 * Serial fisher para RKSoft Xadrez Master 5.8.6.0
 * Por Maycon M. Vitali (0ut0fBound)
 *
 * ATENÇÃO: Este código foi criado para fins de estudo, caso deseje
 * obter o software é necessário que se page a licensa estipulada
 * pelo fabricante.
 */
 
#include <stdio.h>
#include <string.h>
#include <windows.h>
 
#define NAME_PTR_ADDR   0x0012EA48
#define SERIAL_PTR_ADDR 0x0012EA4C
 
#define TITULO_JANELA "Xadrez Master"
 
#define MAX_SIZE 100
 
int main()
{
    HWND cmeHandle;                // Handle da janela do processo
    DWORD cmePid;                  // PID do processo crackme
    HANDLE cmdProcHandle;          // Handle do processo ( depois de aberto )
 
    long lngAddrNome, lngAddrSerial;
    char strNome[MAX_SIZE], strSerial[MAX_SIZE];
 
    char strMensagem[MAX_SIZE*2 + 20];
 
    // Procuramos pela janela do crackme
    if (!(cmeHandle = FindWindow(0, TITULO_JANELA)))
    {
        MessageBoxA(
            0,
            "Execute o xadrez.exe e tente registrar com qualquer serial antes.",
            "Serial Fishing",
            0
        );
        exit(-1);
    }
 
    // Pega e abre processo
    GetWindowThreadProcessId(cmeHandle, &cmePid);
    cmdProcHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, cmePid);
 
    // Obtém os endereços das informações na pilha
    ReadProcessMemory(cmdProcHandle, (void *)NAME_PTR_ADDR, &lngAddrNome, sizeof(lngAddrNome), NULL);
    ReadProcessMemory(cmdProcHandle, (void *)SERIAL_PTR_ADDR, &lngAddrSerial, sizeof(lngAddrSerial), NULL);
 
    // Pega os valores nos endereços obtidos
    ReadProcessMemory(cmdProcHandle, (const void *)lngAddrNome, strNome, sizeof(strNome) - 1, NULL);
    ReadProcessMemory(cmdProcHandle, (const void *)lngAddrSerial, strSerial, sizeof(strSerial) - 1, NULL);
 
    snprintf (strMensagem, sizeof(strMensagem) - 1, "Nome: %s\nSerial: %s", strNome, strSerial);
 
    MessageBoxA(0, strMensagem, "Enjoy!", 0);
 
    printf ("Nome ...: %s\n", strNome);
    printf ("Serial .: %s\n", strSerial);
 
    return 0;
}

Como dito no comentário, não forneci esse código com fins de prejudicar a equipe que desenvolve a ferramenta. Tentarei futuramente disponibilizar análise de malwares e afins para não ter problemas futuros.

Categories: Análise de Binário, Segurança Tags: