10: Engenharia Reversa
-----------------------------------------------------------------------------------------------
____
_.-'111 `"`--._
,00010. .01011, ''-..
,10101010 `111000.. ____ ;
/_..__..-------- ''' __.' /
`-._ /""| _..-''' ___ __ ___ ___ __ __ __' ___ . __
"`-----\ `\ | | | | __ | | |\/| |___ | | | |__] | |\ | |__| |__/ | | |
| ;.-""--.. |___ |__| |__] |__| | | |___ |___ |__| |__] | | \| | | | \ | |__|
| ,10. 101. `. ========================================================================
`;1010 `0110 :
.1""-.|`-._ ;
010 _.-| +---+----'
`--'\` | / / ...:::est:amicis:nuces:::...
~~~~~~~~~| / | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\| / |
`----`---'
[ Aviso ]
Este tutorial foi desenvolvido para fins educativos, o autor deste e o fórum www.RE-B.net não se responsabilizam por mau uso deste material e, os direitos autorias são totais ao criador, deixando livre o fórum Reverse Engineering Brazil de qualquer ato culposo sobre má utilização do conteúdo aqui apresentado. Caso deseje adquirir o software, entre em contato com o fabricante e legalize sua cópia.
[ .NFO ]
Nesse paper vamos trabalhar com uma forma de reversing bem interessante, vamos fazer um serial fishing no programa Driver Checker que está na versão 2.7.5.
Language: Portuguese
Autor: unn4m3D_BR
contato: unn4BR@gmail.com | unn4BR@hotmail.com
Data: 09/11/11 - 23:47
Tipo: Paper
Índice
- 0x00 - O software
- 0x01 - Instalação e Tools
- 0x02 - Análise
- 0x03 - Debugando
- 0x04 - Pescando o Serial
- 0x05 - Agradecimentos
0x00 - O software
Primeiramente vamos conhecer nosso alvo certo? Ok! O Driver Checker, é um programa que em particular, utilizo bastante quando preciso achar um driver. As vezes encontro computadores que precisam de uma formatada básica ou tirar algum vírus, que seja.. e preciso encontrar o driver né? O Driver Checker é bem útil para esse propósito, muito intuitivo, fácil e rápido. Então, tenho certeza que irão gostar.
0x01 - Instalação e Tools
Podemos baixar o Driver Checker - agora chamaremos de DC, ok? - no seguinte endereço:
- http://www.driverchecker.com/
Após baixar, instalamos normalmente.. Para efetuar a análise dele, vamos precisar apenas de dois softwares com as seguintes finalidades:
O primeiro será um scan de cabeçalho PE, para verificar se o software está compactado, ou protegido, e em qual linguagem foi feito. Para isso vamos usar o PeID.
- http://tuts4you.com/request.php?398
O segundo será o nosso debugger (vamos utilizar o OllyDbg), que pode ser encontrado em:
- http://www.ollydbg.de/
Caso queiram utilizar uma outra versão, podem pegar na internet, eu estou utilizando o OllyICE (modificado pelo Hacnho), e quem quiser, poderá baixá-lo aqui:
- http://tuts4you.com/request.php?2375
Bom, agora com as tools em nossas mãos, podemos cair dentro e realizar nosso reversing. :)
0x02 - Análise
Vamos abrir o PeID e passar o scan no DC, logo, percebemos a seguinte informação:
- Borland Delphi 6.0 - 7.0 [Overlay]
Ótimo! Sabemos que o DC foi feito em Delphi e está sem proteção alguma, para confirmar isso vamos na setinha dupla [ -> ] (abaixo do Exit) Plugins > Kripto ANALyzer. Vai abrir uma janela com as informações de criptografia encontradas no nosso target (alvo).
Vemos as seguintes criptografias: ADLER32, BASE64, CRC32, MD5 e ZLIB com seus respectivos endereços ao lado, não existe problema algum. Essas criptografias não nos atrapalharão na nossa busca do serial.
0x03 - Debugando
Agora que temos certeza de que não existe nenhum packer ou compactação no .exe do DC, vamos debugar e seguir na nossa meta.. Pescar um Serial válido.. :D
Abrimos no OllyDbg nosso programa, e então vamos rodar. Para isso, pressione F9.
Ele não deve dar qualquer erro, então, após executar, vamos em: Register, que está no lado superior direito. Logo ao abrir a tela de registro, temos um textbox com o cursor e abaixo um exemplo de serial, que seria algo do tipo:
- 1234-1234-1234-1234
Então, vamos digitar o seguinte serial para teste:
- 1111-2222-3333-4444-5555-6666-7777-8888-9999
Porque esse serial? Porque conforme vamos debugando, saberemos em qual parte estamos, caso precise saber exatamente a posição de cada número, podemos ir mudando, mas, para começo, utilizaremos esse mesmo.
Pois é uma boa sequência para esse tipo de serial, e botei ele bem maior que o exemplo, porque? Eu que quis mesmo, não teve um motivo pra isso .. :D
Após nosso clique no botão: Submit, temos a seguinte mensagem:
- Invalid serial number! Please try again...
Que triste.. ''/ ahiahaihiahaiha, ok, vamos nos aproveitar dessa mensagem e chegar no ponto de validação. Para isso, após pausado pressione ALT + E, assim vamos em uma tela chamada: Executables modules, onde vemos os assemblies carregados por nosso target, procuramos o exetutável do DC e com dois cliques na aba Path, vamos para o código dentro dele.
Em seguinda clique com o botão direito na tela, Search for > All referenced text strings..
CTRL + HOME para subir tudo e botão direito novamente, Search for text..
Esse procedimento nos permitirá encontrar referências de strings dentro do executável, muito compiladores e os próprios programadores, deixam algumas referências, que são muito utilizadas para o reversing.
Então, Digite: serial, pois é uma parte da mensagem que recebemos. Desmarque: Case sensitive, caso esteja marcado e marque: Entire scope e OK. A primeira parada é nossa mensagem:
- 004E571B | MOV ECX, DriverCh.004E5770 | ASCII "Invalid serial number! Please try again..."
Ponha um BreakPoint em todas as referências dessas mensagens, pressione F2 em cima da mensagem, depois CTRL + L para procurar outras e, todas que você achar, pressione F2.
Depois disso, rode o programa e tente novamente efetuar o clicar no Submit, logo verá que o programa irá "brekar" (parar onde você pôs o BreakPoint) e com isso, podemos ver acima da mensagem de erro, a mensagem de: Congratulations, e mais acima um salto JNZ.
Ele é o primeiro a ser visto, logo acima das mensagens.
Explicação sobre o salto:
- [ http://faydoc.tripod.com/cpu/jnz.htm ], o salto JNZ
Significa que.. somente saltará, se o flag Z for igual a zero, como nosso serial está errado, o flag será zero e iremos saltar para a mensagem de erro.. E agora? Como mudar isso? :D
0x04 - Pescando o Serial
OBS .: Para pescar o serial sem perder tempo, vamos utilizar uma forma simples e muito fácil. Para entender o porque eu pular algumas coisas, e ir direto ao ponto, segue a explicação.
Todo programa feito em Delphi tem essa estrutura que vocês podem ver no DC, cada linguagem tem sua forma de "montar" o programa, meio obvio isso né? Pois bem, é com essa forma de montar o programa, que ficamos acostumados a apenas olhar para o assembly e saber onde está, a validação, ou, onde devemos por um BreakPoint sempre terá a mesma "cara".
Como eu já sei que acima desse JNZ sempre existirá uma CALL, que é o local onde a comparação do serial é feita, logo, ponho ali um BreakPoint com F2 e faço o mesmo processo de rodar novamente e clicar em Submit, pois isso irá gerar a mensagem de erro e antes disso, irá parar no meu BreakPoint, e é ai que começa nossa análise do código.
Paramos então na CALL, e o que vemos? Um número que é parte do meu serial no registrador EAX, e outro que está em hexa no registrador EDX, logo, podemos supor que seja um valor comparado com nosso serial.. então, vamos mudar e ver no que da .. :D
EAX 0214E414 ASCII "66655" <-- AQUI UM PEDAÇO DO MEU SERIAL DIGITADO
ECX 00000000
EDX 0156ECAC ASCII "4E314" <-- AQUI UMA PARTE DO SERIAL VERDADEIRO
Como meu serial foi bem sugestivo, eu já sei onde mudar, e pelo que vemos, ele está invertido, logo o que tenho que fazer é:
- Achar a parte "66655" que na verdade é "55666", pois está invertido (eu sei disso pois lá no começo eu digitei o serial todo em ordem).
- Escrever no lugar do "55666" o valor de "413E4" que seria "4E314" invertido.
- Rodar o programa novamente e verificar se ele passa do salto JNZ sem pular.
Meu serial modificado ficou da seguinte forma:
- 1111-2222-3333-4444-5541-3E46-7777-8888-9999
Agora que alterei o meu serial antigo, empregando a nova alteração, verifico que com o BreakPoint na CALL, é possível ver claramente nos registradores a comparação abaixo:
EAX 0214E414 ASCII "4E314" <-- AQUI
ECX 00000000
EDX 0156ECAC ASCII "4E314" <-- AQUI
EBX 00000000
ESP 0012FB94
EBP 0012FC10
ESI 00000000
EDI 0214AFCC
EIP 004F477C DriverCh.004F477C
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 1 DS 0023 32bit 0(FFFFFFFF) <-- FLAG Z = 1
S 0 FS 003B 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000246 (NO,NB,E,BE,NS,PE,GE,LE)
ST0 empty -0.7618686529160622080e+4731
ST1 empty -UNORM FDD8 7FFDE000 00120000
ST2 empty 1.0092781390466328576e+2415
ST3 empty -UNORM FBE0 01197A60 00090270
ST4 empty -UNORM 8098 00000030 890FC020
ST5 empty 9.9712719555298426880e-4933
ST6 empty -UNORM FAEC 00000000 B140FA0C
ST7 empty -5.4919037670638080000e+4526
3 2 1 0 E S P U O Z D I
FST 4000 Cond 1 0 0 0 Err 0 0 0 0 0 0 0 0 (EQ)
FCW 1372 Prec NEAR,64 Mask 1 1 0 0 1 0
Com isso, nosso salto JNZ, encontra-se com o flag Z = 1, o que quer dizer que não pula..
Seguimos o fluxo e encontramos a mensagem..
- 004F4868=DriverCh.004F4868 (ASCII "Congratulations! This copy is registered successfully.")
Aqui uma parte do código comentada para estudos..
004F4728 |. E8 1308F1FF CALL DriverCh.00404F40 ; inverte uma parte do serial
004F472D |. 8B45 AC MOV EAX, [LOCAL.21] ; eax recebe o valor invertido
004F4730 |. 8D55 B0 LEA EDX, [LOCAL.20]
004F4733 |. E8 2089FBFF CALL DriverCh.004AD058 ; gera um hash
004F4738 |. 8B45 B0 MOV EAX, [LOCAL.20] ; eax com o hash
004F473B |. B9 05000000 MOV ECX, 5
004F4740 |. BA 01000000 MOV EDX, 1
004F4745 |. E8 9609F1FF CALL DriverCh.004050E0
004F474A |. 8D55 A8 LEA EDX, [LOCAL.22]
004F474D |. 8B45 DC MOV EAX, [LOCAL.9] ; eax com um pedaco do meu serial
004F4750 |. E8 FF4BF1FF CALL DriverCh.00409354
004F4755 |. 8B45 A8 MOV EAX, [LOCAL.22] ; eax com pedaco do meu serial
004F4758 |. 8D55 CC LEA EDX, [LOCAL.13]
004F475B |. E8 6C4EF1FF CALL DriverCh.004095CC
004F4760 |. 8D55 A4 LEA EDX, [LOCAL.23]
004F4763 |. 8B45 EC MOV EAX, [LOCAL.5] ; eax c/ valor que sera comparado
004F4766 |. E8 E94BF1FF CALL DriverCh.00409354
004F476B |. 8B45 A4 MOV EAX, [LOCAL.23] ; eax c/ valor que sera comparado
004F476E |. 8D55 C8 LEA EDX, [LOCAL.14]
004F4771 |. E8 564EF1FF CALL DriverCh.004095CC
004F4776 |. 8B45 CC MOV EAX, [LOCAL.13]
004F4779 |. 8B55 C8 MOV EDX, [LOCAL.14]
004F477C |. E8 4B08F1FF CALL DriverCh.00404FCC <- CALL QUE COMPARA O SERIAL
004F4781 |. 75 3D JNZ SHORT DriverCh.004F47C0 <- NOSSO SALTO
Após esse trabalho todo, podemos ir em: About para verificar, e lá obtemos a informação:
- Version 2.7.5
- Serial Number: 1111-2222-3333-4444-5541-3E46-7777-8888-9999
E então, temos nosso DC registrado lindamente .. ehehe
Poderiamos até dar uma analisada melhor e gerar um keygen pra ele, porém não é esse o propósito desse paper, então, fica aqui a sugestão e a parte do código comentanda.
O pedaço de rotina onde a comparação é feita, é exatamente este. Basta um pouco de paciência para entender esses números que são comparados e geram o serial para o DC.
0x05 - Agradecimentos
Agradeço a oportunidade de está escrevendo esse paper sobre reversing.. aos teams:
- BRC
- CTB
- RE-B
- ARTeam
- SnD
- AT4RE
Ao pessoal do CrackSLatinoS por tudo..
e em especial para minha princesa que me ajuda a crescer, entende esses meus momentos nerds, está comigo sempre e a quem devo meu amor.. Mayara Rangel.
Alguns, posso ter esquecido de agradecer, me perdoem..
Pois, igualmente vocês merecem meu agradecimento e gratidão.
Um forte abraço e bjxx pra todos.. :D
unn4m3D_BR - Reverse Engineering Brazil [ 2011 ]
_____
.: :.
(_________)
__ | |
.: :. | |
(______) / /
|| / /
|| / / _
_ || | | (_) ,
(_) \\010| | .; _..--,
\\.0101010110. ;': ' ',,,\ .^. .^. .^.
.0101011010101. ;_; '|_ ,'
.100101010101011. | .;;;;., ,': .^. '. .^.
,;::;:::.. ..;;;;;;;;.. :_,' .;'
.^. .' '':::;._.;;::::''''':;::;/' .;:;
. ':::::::;;' '::::: ...;: .^.
.^. ':::' /':::; ..:::::;:..::::::::.. .^.
.^. .^. ; ,'; ':::;;...;::;;;;' ';;. .^.
,,,_/ ; ; ';;:;::::' '.
.^. ..' ,' ;' ''\ '
.^. ' ''' .^. ' ;'. .^. .^.
: : .^.
ack_syn - 200.218.196.14/zine/
eremitah - cogumelobinario.hashit.org
mentebinaria - mentebinaria.com.br/zine/
bugsec - bugsec.com.br/zine/
c00kies - c00kies.org/Zine/
Von natur - 0fx66.com/files/zines/cogumelo-binario/call/
Ping - ping.eti.br/docs/01/05/
unn4m3D_BR - re-b.net/zines/cogumelo-binario/