Exploit-DB #19316
Description: SGI IRIX 6.5.2 - 'nsd' Information Gathering
Type: remote
Platform: irix
Date: 1999-05-31
Author: Jefferson Ogata

Exploit:
/*
source: https://www.securityfocus.com/bid/412/info

A vulnerability has been discovered in the nsd service, as included by SGI in Irix 6.5.x. The vulnerability allows remote users to access potentially sensitive pieces of information, including, but not limited to, NIS map information, shadow password files, and remote connections. 
*/


/******************************************************************************

IRIX 6.5 nsd virtual filesystem exploit

Author: Jefferson Ogata (JO317) <ogata@pobox.com>

Please note that this program comes with NO WARRANTY WHATSOEVER. Your use
of this program constitutes your complete acceptance of all liability for
any damage or loss caused by the aforesaid use. It is provided to the
network community solely to document the existence of a vulnerability
in the security implementations of certain versions of IRIX, and may not
be used for any illicit purpose. Many of the details of the bug this
program exploits have been available to users of SGI's online support
system since February 1999. The current revision of IRIX (6.5.3) corrects
this bug, at least enough to stop this particular exploit, and I strongly
encourage you to bring your systems up to date as quickly as possible.

With IRIX 6.5, SGI has moved all name services, NIS services, and DNS
lookups into a userland process called nsd, which exports the results of
the queries it fields into a virtual filesystem. The virtual filesystem is
normally mounted onto the directory /ns by the program /sbin/nsmount, which
is invoked by nsd on startup. The nsd daemon itself is exporting the
filesystem via NFS3 over a dynamically bound UDP port -- rather than a
well-known or settable one -- typically in the 1024-1029 range. On a
desktop system, 1024 is a good bet, since nsd is usually the first
RPC/UDP service to be started.

The NFS filesystem is not registered with mountd, so there is no way to
query mountd for a mount filehandle. But because the NFS port is fairly
easy to discover through port scanning, and because the mount filehandle
nsd uses is simply a string of 32 zeroes, it is trivial to mount the nsd
filesystem from a host anywhere on the Internet. nsd will serve an array
of NFS requests to anyone. Furthermore, because the service's NFS port is
bound dynamically, it is difficult to protect it with a firewall; it may
change from one system start to another, or if the daemon is killed and
restarted.

This program can successfully mount the nsd-exported virtual filesystem
from a remote host onto a machine running IRIX 6.4 or higher. It makes use
of the MS_DOXATTR mount flag defined in IRIX 6.4 and higher. I do not know
what this flag does at the NFS protocol level, but it allows the client to
ask the NFS server not to enforce certain permissions controls against the
client. I don't know whether any other vendor NFS client systems support
this flag. A clever person might write a userland NFS client that would
accept an initial handle, NFS port, etc. as arguments.

On an SGI with SGI C compiler, compile with:

    cc -o nsdadv nsdadv.c

Run it this way:

    nsdadv /mnt sucker.example.com 1024

with obvious substitutions.

So what are the security implications of this? Well, at the very least, the
nsd filesystem on an NIS server reveals the NIS domain name, and what maps
it contains, as well as what classes are being used.

By exploring the filesystem shortly after it has been mounted I have been
able to retrieve data that should be hidden from me, including shadow
password entries from a remote system's shadow file.

Beyond retrieving keys and maps, you can also monitor the filesystem for
changes. A great deal of information is leaked through the contents of the
nsd filesystem. For example, if host A looks up a host B's IP address, a
file named B will appear in the /.local/hosts.byname directory in A's nsd
filesystem. The file's contents will be the IP address.

By the way, though you be unable to chdir into a particular location in
the nsd filesystem, you may yet succeed under slightly different
conditions. Eventually you can do it. I'm not sure why or when, but nsd
gets picky sometimes. Eventually it relents. Specifically, I've found that
the entire nsd filesystem appears readable for a few seconds after it is
initially mounted. If you can't look at something, unmount the filesystem,
remount it, and try again immediately. It also seems that a stat() is
sometimes required before a chdir(). Your mileage may vary, but keep
trying. You may wish to write a script to mount the nsd filesystem, explore
and take inventory of its contents, and unmount the filesystem quickly.

Once you've chdir'd into a directory, it appears you can always read it,
although you can't necessarily stat its contents. This suggests a strategy
of spawning a group of processes each with its cwd set to a subdirectory of
the nsd filesystem, in order to retain visibility on the entire filesystem.
Each process would generate an inventory of its cwd, and then monitor it
for changes. A Perl script could do this well.

Another thing: it is possible to create an empty file in nsd's exported
filesystem simply by stat()ing a nonexistent filename. This suggests a
potential DoS by creating many files in a directory.

Remember that the system keeps a local cache in /var/ns, so you may have
to wait for cached entries on the target host to expire before you'll see
them reappear in the virtual filesystem.

For some fairly extensive info on the nsd implementation, take a look at:

    http://www.bitmover.com/lm/lamed_arch.html

******

What got me into all this was that I found I could no longer run services
chrooted if they required DNS. It took considerable effort to come up with
a solution to this. This was a fundamental change from IRIX 6.4, and I know
I'm not the only one who finds the nsd implementation to be a generally
unpleasant