Por: Pockets
O que estiver entre [ e ] foi adicionado pelo CyberLord
1- O que fazem estes
pequeninos insectos?
Um virus de computador funciona da mesma maneira do que um virus
Biológico. O virus tenta aproveitar ao máximo as células de
modo a conseguir sobreviver e procriar.
Os virus biológicos matam o anfitrião no fim, mas os MEUS virus não. Eu NÃO apoio
código com intenção de destruir. Não é que eu goste de todas as pessoas... Não é que
eu não queira magoar ninguém... É porque os virus precisam de hipóteses para se espalharem!
Não necessitam de acabar nos laboratórios da Mcafee 2 meses antes da sua data de activação.
2-Ok, e quais as bases de um virus?
A maneira de trabalhar de um virus é esta:
Passo 1: Encontra um anfitrião, ou seja, um sitio onde se instalar o virus. Geralmente os *.com ou *.exe, apesar de muitos virus infectarem outros ficheiros e ocasionalmente a BootSector.
Passo 2: Verifica este ficheiro para ver se está infectado. Isto inclui ter a certeza de que o ficheiro tem permissões de leitura/escrita, ter a certeza de que ele não faz parte de nenhum anti-virus,
e ter a certeza de que adicionando o nosso virus a esse ficheiro, isso não afectará a maneira de como o Sistema Operativo corre esse ficheiro.
Passo 3: Abriri o ficheiro e (talvez) retornar ao passo 2. Se existir um erro, retornar ao passo 1.
Passo 4: Inserir o nosso código no ficheiro.
Passo 5: Fechar o ficheiro e deixar o computador continuar a trabalhar.
A maioria dos virus são escritos em Asm.
A linguagem Assembler é muito mais poderosa e compacta do que a maioria das linguagens, mas C/C++ é aceitável para se COMEÇAR! Eu irei basicamente fazer este tutorial em Asm...
Existem 2 tipos de virus que nós podemos escrever uma vez entendida a teoria básica e um pouco dos comandos de assembler... Os que escrevem por cima OVERWRITING, e os que escrevem a partir de
um certo sitio APPENDING. Os OVERWRITING DESTROEM o programa que os vai albergar, deixando "talvez" um bocadinho do programa original. Isto é mau, pois o virus pode ser detectado MUITO MUITO
facilmente [pois o programa não corre, ou correrá com defeitos]. Os APPENDING, por outro lado, MODIFICAM o programa que os alberga, e deixam que ele corra perfeitamente. [Ninguém notará nada, pois
o ficheiro continuará a funcionar].
Ideia básica de um virus overwriting:
1- Encontra o primeiro ficheiro... (os ficheiros .com são facilmente achados e escritos por cima)
2- Abre o ficheiro...
3- Verifica se já está infectado...
4- Escreve o nosso código por cima do código do ficheiro...
5- Fecha o ficheiro...
1- Salta para o nosso código que está no ficheiro...
2- Coloca as bytes originais do ficheiro no seu lugar de origem...
3- Encontra o primeiro ficheiro...
4- Abre o ficheiro...
5- Verifica se já está infectado...
6- Se não estiver infectado, escreve o corpo do virus para o fim do ficheiro...
7- Grava as bytes originais do anfitrião...
8- Escreve instruções para saltar para o nosso código no inicio do ficheiro anfitrião.
9- Fecha o ficheiro...
10- Salta para as bytes do anfitrião, e acaba de correr o programa...
Umas coisas técnicas que precisas de saber...
Nota: Eu assumirei que tu estás a aprender como infectar ficheiros .com, e por isso só incluirei informação acerca deles. Infectar ficheiros .com é simples, e é por isso a maneira mais fácil de começar. A rasão pela qual os ficheiros .com são mais fáceis de infectar é porque eles são lidos directamente para a memória, a partir do disco. Os .exe e outros ficheiros contêm cabeçalhos ou outra informação que é necessária à sua execução.
Informação geral sobre ficheiros .com:
Como eu disse na nota, os ficheiros .com são lidos a partir do disco directamente para a memória. Um PSP (Program Segment Prefix) é construido a partir do offset 0h até ao offset FFh da memória que é alocada para o programa, e o código é lido e executado para baixo do endereço 100h. O PSP não é gravado para o disco, é simplesmente um espaço para o stack, DTA, e outras coisas que para já não te precisas de preocupar. O código que é executado, começa e acaba no ficheiro
.com, e um sitio temporário para armazenar a informação é colocado ANTES do código actual e enche FFh bytes. O ficheiro .com é lido do disco e colocado no offset 100h, onde começa a sua execução. Os ficheiros .exe e mais alguns, contêm cabeçalhos e outras informações que são lidas para a memória e gravadas no disco. Esses cabeçalhos incluem o stack e outras informações, como por exemplo onde começa a execução do ficheiro. Isto faz com que infectálos seja mais díficil (para os newbies)
do que infectar um ficheiro .com. Infectar um .com significa simplesmente alterar o seu código, infectar os .exe e outros involve alterar o seu cabeçalho e código.
Esta função irá encontrar o PRIMEIRO ficheiro no directório ACTUAL, que tenha a informação no offset especificado no registo DX... Seguidamente move a informação deste ficheiro para o DTA (Data Transfer Area). Esta é uma área no PSP dos ficheiros .com. O DTA está localizado no offset 80h do ficheiro .com. Porém, o DTA pode ser realocado pelo INT 21h do DOS e função 1ah.
Informação encontrada no DTA:
Assumindo que um ficheiro é encontrado, esta informação é movida para o DTA. Os offsets na tabela seguinte são os do DTA, não do ficheiro .com!
0h 21 duplica os 0 - Reservado para o DOS
15h db 00 - Atributos dos ficheiros.
16h dw 0000 - Atributos de tempo dos ficheiros.
18h dw 0000 - Atributos de data dos ficheiros.
1ah dd 00000000 - Tamanho do ficheiro.
1eh db 13 dup 0's - Asciiz do nome do ficheiro.
Vamos supor que não o movimentámos e que temos um ficheiro ali.
Para inserir o nome do ficheiro no registo ax, fariamos isto:
mov ax, [80h + 1eh]
Movendo o DTA:
Como disse anteriormente, o DTA terá de ser movido de 80h para preservar que as funções dos ficheiros. Isto é feito com a duplicação de 42 bytes para o seu uso, e move-se para ali.
mov ah, 1ah
mov dx, offset newdta
int 21h
newdta db 42 dup (0)
mov ax, [newdta + 1eh]
mov ah, 1ah
mov dx, 80h
int 21h
Explicando muito simplesmente, o DTA é apenas o lugar onde é localizada informação temporária sobre os ficheiros. :))
Notas sobre o binário:
Se sabes como é que isto funciona passa à frente, mas muita gente não sabe, portanto...
Um número binário é: 0000b.
Binário é um sistema de Base 2.
Base 2 significa que existem 2 números. 0 ou 1. 0 representa que este local não tem valores. 1 representa que este local tem valores.
0001 = 1, 0010 = 2, 0011 = 3. Cada lugar é igual a duas vezes o valor prévio. O bit na primeira posição é 1, o bit na segunda posição é 2, o bit na terceira posição é 4, etc.
Notas sobre Hexadecimal:
Se sabes como é que isto funciona passa à frente, mas muita gente não sabe, portanto...
Um número hexadecimal é: 0f6h.
Hexadecimal é um sistema de base 16.
A sua ordem é: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10.
10 em Hexa = 16 em decimal. Brinca um bocadinho com isto na tua cabeça, pois vais precisar.
Notas sobre os tamanhos:
Se sabes como é que isto funciona passa à frente, mas muita gente não sabe, portanto...
A informação pode ser representada por bits, nibbles, words, e bytes.
Investiga por ti próprio, pois isto deve ser elementar para um programador de assembler.
[1 bit = 0, 1 nibble = 4 bits = 0000, 1 byte = 2 nibbles = 8 bits = 00000000, 1 word = 2 bytes = 4 nibbles = 16 bits = 0000000000000000]
[Agora digam lá se eu não fui bonzinho, hã?]
Os que vais utilizar mais são: Bit, Byte, Word and DoubleWord (32 bits). Bit é o bloco básico de informação, ele pode ser ou 0 ou 1, e apenas um 0 ou um 1. Uma Byte são 8 bits, e é representada por exemplo, 0fffh, 0234h, 2234h, etc. Uma DWORD (doubleword) são 2 words somadas. É obvio como é que se escreve isto, né?
[Representa-se po FFFFh:FFFFh]
5- Au, doí-me o cérebro com tantas coisas.....
Deixa lá, hás-de te habituar, as únicas coisas que tens de memorizar são os sistemas de numeros(hex, bin), os tamanhos da informação e os operadores de Assembler!
Coisas que deves de aprender:
Assembler, mas isso é óbvio.
Aprende sobre "polymorphism", "stealth", e "encriptação".
Aprende sobre as funções de TSR.
Aprende sobre os segments e offsets, mas em detalhe!!
Aprende a optimizar o teu código de maneira a ele ser rápido e compacto.
Aprende tunneling.
[Aprende sobre memória no computador. Como o teu virus irá ficar residente, ele vai ocupar memória, então aprende como é que podes pregar uma rasteira aos programas de gestão e visualização da memória, para que os teus virus não sejam detectados facilmente].
Ok, primeiro vou mostrar-te código sobre virus overwriting, embora não sejam estes que tu queiras escrever para sempre.
Este tutorial é suposto começar a ensinar o mais fácil, e quando acabares de o ler, deves saber mais do que quando começas-te. Espero que vocês passem deste para os vossos próprios appending virus, e depois talvez tentar encriptação, depois TSRs, e depois infectar os EXE, depois polimorfismo, depois BootSector, depois Multipartite, etc etc etc...
Estou a assumir que tu estás a utilizar o Tasm 2.0, ou melhor, considerando que eu estou a utilizar o Tasm 5.0....
Código Fonte
Basicamente, este virus encontra o primeiro ficheiro na directoria, abre-o, escreve-se a si próprio para o ficheiro em cima da informação lá contida, fecha-o, e grava-o, e depois sai para o DOS.
Bom, este virus é patético. [Pockies, deixa lá, é patético, mas ensina as bases :))]. Imprime-o, ri-te, mas lembra-te que ele faz o que faz e reproduz-se :)). Se não entendes o funcionamento básico deste virus, lê mais código que NÃO SEJA DE VIRUS,
revê os códigos de Asm, e tenta outra vez. NÃO CONTINUES se não conseguires entender o código aqui escrito!!
7- Psst, Pocket. Este tutorial está a fazer com que pareças esquizofrénico.
Cala-te. Se isto ensinar alguém, então tenho o direito de parecer estúpido.
[Pockies, não te chateies, tu de qualquer maneira sempre foste doido, mas estúpido nunca.]
8- Ok, consegui entender a desculpa do virus que foi incluido em #6.
Ainda bem. O virus em #6 é apenas o mais simples que podes fazer. Certamente ele ficará ali, e vai-se re-escrever (overwrite) A ELE PRÓPRIO, repetidamente... [E PENSAS QUE É MAU? Bom, não é lá grande coisa, mas sempre ensina.] Mas demonstra os virus overwriting.
O próximo tipo de virus que vou mostrar são os appending. Preciso de dar umas breves explicações antes de te mostrar...
Este tipo de virus PRECISA de manter as instruções do ficheiro anfitrião, que ele escreve por cima. Um appending virus não é executado do 100h, como os overwriting são, portanto precisamos de encontrar de onde é que estamos a executar. O sitio é chamado 'delta offset'.
Notas sobre appending:
Como foi dito, nós precisamos de gravar as bytes que são modificadas no ficheiro e restaurálas quando estiver tudo feito. Precisamos também de mover o DTA para que a cauda do programa não seja re-escrita.
Precisamos também, de ler e gravar as bytes originar do ficheiro .com que estamos a infectar, para ele executar correctamente mais tarde.
Pricisamos de um salto para o nosso código no offset 100h.
O MAIS importante sobre um virus appending, é que chamamos de 'delta offset'. Isto é apenas o número de bytes que o nosso código vai ser movido. Sem isto, o nosso virus vai ser apenas um bocado de código que mal funciona. O metodo que (talvez o mais fácil) nós utilizaremos, começa com CALL, depois um
POP BP, e depois vamos subtrair onde o offset DEVE de estar por BP... A primeira coisa que tu queres saber, é porque é que este delta tem de utilizar sempre o BP para ser armazenado. Bom, de verdade tu nem sempre tens de utilizar o BP para armazenares o delta... Primeiro tens de saber como é que o CALL trabalha [tens duas soluções,
ou vais ler um livro sobre asm, ou continuas a ler este tut ;) Sim, o Pockies explica tudinho]. Quando tu fazes um CALL para qualquer coisa, significa que queres correr a rotina e retornar onde estavas antes. CALL precisa de manter uma relação de onde tu estás, para poder voltar, certo? Bem, ele faz isto, usando o PUSH para o offset
da PRÓXIMA instrução para o stack. Portanto to fazes um POP para o BP e depois subtrais o BP donde o offset DEVE ESTAR... Um bocadinho dificil de entender para algumas pessoas, então aqui está uma ajuda. Faz uma figura mental de umas escadas... Agora uma vela no degrau 7, e tu estás no degrau 1. Imagina que alguém te põem no degrau 3.
Agora a partir do degrau 1 to terias de andar 7-1 degraus = 6 degraus. Se tu andasses 6 degraus depois de alguém te colocar no degrau 3, to passarias a vela!! Mas, se tu subtraires o teu degrau, dos degraus que tu terias de andar, to vais obter o 'delta offset'.. (degrau 3 - distância anterior (6)) = 3. Mais 3 degraus e tu apanharias a vela.
Percebes-te? O 'delta offset' é basicamente a maneira como to mantens uma relação dos novos offsets do código, adicionando onde o código estava quando foi compilado e quantas bytes foi movido. O termo 'delta offset' significa "mudança de offset". O termo 'delta' vem do alfabeto grego e é geralmente utilizada para representar uma "mudança de" na matemática
[bom, por acaso eu uso o delta mais em física e química do que matemática, mas tudo bem].
Uma maneira de identificar se o ficheiro já está infectado é sempre bom, considerando que nós não queremos estar repetidamente a aumentar o tamanho de um ficheiro para sempre.
9- Ok, eu entendi isso, onde está o código para isso? [Pockies deste ai uma granda explicação ;)]
Existem muitos exemplos no IRC e na Web para os virus appending... [Tens apenas de procurar nos sitios certos :))]
Portanto isto é trivial...
MAS...
Mas vou mostrar algumas rotinas importantes e como o virus trabalha. E como o virus overwriting este vai ser tão estúpido como o outro... [Agora já sei porque é que em 7, o Pockies começou a ter cara de estúpido, por causa do código ;>]
Appending Virus 101:
Os virus appending geralmente infectam os ficheiros adicionando o seu código ao fim do ficheiro, e escrevendo uma instrução de salto(jmp) por cima das primeiras bytes. A instrução de salto(jmp) transfere o controlo do ficheiro original para o virus. Depois do controlo estar transferido, precisamos de encontrar o Delta Offset...
A instrução jmp:
O nosso virus precisa de transferir o controlo do programa anfitrião para nós. Isto é feito, escrevendo por cima das primeiras bytes com um jmp para o nosso código. (As bytes vão ser recolocadas mais tarde). O jmp para o nosso código vai ter o comprimento do anfitrião ANTES da infecção, pois nós estamos a escrever o nosso código para o fim do ficheiro e a executar a partir daí.
Existem algumas maneiras diferentes de encontrar o tamanho do ficheiro original, e o tamanho não é mudado até o ficheiro ser fechado, portanto isto pode ser colocado em qualquer lugar.
2 maneiras de obter o tamanho original do anfitrião:
Podes obter o tamanho pelo DTA, ou podes obter chamando a função 4202h, Int 21h (lseek eof). Descobre por ti próprio.. :)
Patching o anfitrião para este trabalhar correctamente:
Precisamos de ler o primeiro par de bytes que infectarmos no ficheiro, para que este não se demonstre suspeito. Depois da infecção, o anfitrião deve correr da seguinte maneira:
A instrução jmp passa o controlo para o virus.
O virus vai então infectar outro ficheiro.
O virus vai seguidamente restaurar as bytes para o ínicio.
O virus dá outra vez o controlo o ficheiro anfitrião.
O anfitrião corre normalmente.
Antes de infectar o ficheiro, tu deves de utilizar a função 3fh, Int 21h para ler as bytes originais e gravá-las algures no virus.
Depois do virus acabar de correr, as bytes devem ser restauradas e executadas. Os operadores Movs* podem ser utilizados para moverem para a sua posição original as bytes. Movs* (movsw, movsb, etc) lêem o que está a ser endereçado por ds:si e põem isso na área endereçada por es:di.
Lembra-te, si = origem, di = destino.
Código para restaurar as bytes:
mov di, 100h ;Endereço 100h...
lea si, [offset oldbytes + bp] ;Onde as bytes originais estão.
mov cx, (# of bytes) ;cx = numero de vezes para 'rep' um operador
rep movsb ;movsb n numero de vezes, onde n = cx
Então "mov bp, 100h, jmp bp" são suficientes.
Isto deve ser suficiente para que comeces, mas vamos limar a execução de virus appending:
1. Jmp para o código do virus.
2. Encontra o delta, move o DTA, etc.
3. Encontra o ficheiro a infectar.
4. Verifica se já está infectado.
5. Abre o ficheiro, lâ as primeiras bytes, e grava-as.
6. Escreve a instrução jmp no inicio do ficheiro, e grava o virus no fim desse ficheiro.
7. Close newly infected file and execute current host as normal.
Recomendo vivamente que se movam as bytes originais para o seu lugar original ANTES de se fazer algo, e como isto é facilmente esquecido, e se fizeres isto a seguir a infectares outro ficheiro, vais mover as bytes erradas para o ficheiro errado, provocando um crash [E é claro que o virus não vai trabalhar :(( ]
Ver se já foi infectado o ficheiro:
Existem algumas maneiras para fazer isto, mas vou explicar as 2 mais comuns. A maneira mais fácil é por uma marcação nas primeiras bytes. O método melhor e mais optimizado é verificar se o ficheiro foi infectado utilizando o offset do JMP no ínicio do ficheiro. A byte de marcação é incluida no código dos virus overwriting.
O método de marcação é simples, basta apenas ler as primeiras 4 ou mais umas bytes do ficheiro que queres infectar, gravas essas bytes, escreves o jmp e o offset para o virus, e depois um marcador. Depois basta simplesmente comparar a 4ª byte do ficheiro com a tua byte de marcação. Outra maneira fácil, mas que confunde algumas pessoas, é ler as primeiras 3 bytes como é normal, e comparar a segunda e terceira com o que o offset do nosso virus VAI SER, se o ficheiro estiver infectado. Lembra-te apenas de que o offset do jmp que tu escreves para o ficheiro
É o tamanho do ficheiro original ANTES da infecção. Portanto basta saberes o número onde o offset do jmp IRÁ ESTAR- se o ficheiro estiver infectado, obtens depois o tamanho e subtrais por 3 (o tamanho da instrução jmp), e comparas com o número onde o offset do jmp DEVERIA DE ESTAR infectado.
jmp_offset - tamanho_do_ficheiro_com_virus - 3, será igual a 0 se o ficheiro estiver infectado. (Usa uma instrução de comparação :))
Tou com a sensação estranha de que queres ver código, portanto...
Comentado pelo kRaCkBaBy no seu retorno à scene dos virus!
Para veres o código basta clicar aqui.