Bugtraq mailing list archives

Predictability Problems in IRIX Cron and Compilers


From: jose () THEGEEKEMPIRE NET (jose nazario)
Date: Wed, 21 Jun 2000 12:05:51 -0400


Crimelabs, Inc.                                      www.crimelabs.com

                        Security Note
             Crimelabs Security Note CLABS200004

          Title: Poor Tempfile Use in IRIX: Compilers and Cron
           Date: 21 June, 2000
    Application: MIPSPro Compilers (7.1, 7.2.1 tested), cron
      Platforms: IRIX 6.3, 6.5
       Severity: Moderate, higher in some instances
         Author: Jose Nazario (jose () thegeekempire net)
  Vendor Status: Contacted (late May, 2000), bug ID's filed
                 792237 (cron) and 792239 (compilers)
            Web: (real soon now, we promise)
       Solution: None yet, but ensure umasks are at least 022, 077
                   preferred

Description:

Tempfiles really aren't new, but everyone's usually rather lazy about
their use. I figured I would get this notice out about SGI's poor use of
them in their base system (cron) and the MIPSPro compilers (version 7.1
and 7.2.1 tested). Not earth shattering, but it's something that should be
fixed while we're at it.

The MIPSPro compilers (version 7.2.1 is for IRIX 6.5) are a commercial
package from SGI that is not part of the base IRIX 6.5 installation. They
support C, C++, F77 and F90 languages and offer excellent optimization and
parallelization. Cron, however, is part of the base distribution of IRIX.

Note: This is kinda lengthy, but it's mainly temp-watch output surrounded
by a lot of fluff.

The tool used to monitor the tempfile creations was the L0pht's temp-watch
(http://www.l0pht.com/advisories/watch.txt, thanks Mudge). The systems
tested were an SGI O2 running IRIX 6.5:

        IRIX workstation 6.5 05190004 IP32

and an O2 running IRIX 6.3:

        IRIX workstation2 6.3 12161207 IP32

Both systems are affected by the bugs described here.

------------------[ Cron:

As cron does it's housekeeping duties specified in the various crontabs,
it creates temporary files. They couldn't be more predictable, stepping up
one letter each time, no matter who is running the instance of cron (in
this case root or sys):

+  -rw-------  1  sys      sys   83     Jun  6 14:00 /tmp/croutHBCa0005g
-  -rw-------  1  sys      sys   83     Jun  6 14:00 /tmp/croutHBCa0005g
+  -rw-------  1  root     sys   97     Jun  6 14:03 /tmp/croutKBCa0005g
-  -rw-------  1  root     sys   97     Jun  6 14:03 /tmp/croutKBCa0005g
+  -rw-------  1  root     sys   94     Jun  6 14:08 /tmp/croutLBCa0005g
-  -rw-------  1  root     sys   94     Jun  6 14:08 /tmp/croutLBCa0005g
+  -rw-------  1  root     sys   131    Jun  6 14:15 /tmp/croutMBCa0005g
-  -rw-------  1  root     sys   131    Jun  6 14:15 /tmp/croutMBCa0005g
+  -rw-------  1  root     sys   115    Jun  6 14:17 /tmp/croutNBCa0005g
-  -rw-------  1  root     sys   115    Jun  6 14:17 /tmp/croutNBCa0005g
+  -rw-------  1  sys      sys   83     Jun  6 14:20 /tmp/croutOBCa0005g
-  -rw-------  1  sys      sys   83     Jun  6 14:20 /tmp/croutOBCa0005g

The good news is that cron doesn't seem to follow symlinks, it will just
alter the name (ie to croutOBCb0005g). Still, it should be considerably
more random to prevent being abused in a larger scheme.

(in following temp-watch examples, the ^- lines, corresponding to the
deletion of a file, have been removed for brevity's sake).

Invoking crontab -e to edit my crontab as a regular user demonstrates the
predictability again:

+  -rw-r-----  1  jose     user     0    Jun  8 18:28 /tmp/crontaba0020m
+  -rw-r-----  1  jose     user     0    Jun  8 18:28 /tmp/crontaba00218
+  -rw-r-----  1  jose     user     0    Jun  8 18:28 /tmp/crontaba00217
+  -rw-r-----  1  jose     user     0    Jun  8 18:28 /tmp/crontaba00219
+  -rw-r-----  1  jose     user     0    Jun  8 18:28 /tmp/crontaba00213
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba0021C
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba00212
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba0020f
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba0021T
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba0021N
+  -rw-r-----  1  jose     user     0    Jun  8 18:29 /tmp/crontaba0021I

Again, temporary files are simple changes of the last three positions,
which we can easily predict as they're often increments (but not always)
of the last positions.

It looks like cron is using mktemp(), when it should be using mkstemp()
and a good PRNG for increased entropy.

----------[ Compilers and their tempfiles:

The compilers in the MIPSPro set are also affected by the creation of
predictable tempfiles. While this has been tested on both IRIX 6.3 with
the 7.1 versions of the compilers and found also, we report it only for
the currently shipping product, 7.2.1.

MIPSPro C compiler:
I  c_fe                 02/26/99  C Front-end, 7.2.1

The command

% cc -c usage.c

yields the following tempfiles:

+  -rw-r-----  1  jose     user  88     Jun  5 18:32 /tmp/ctmL.AAAa001JC
+  -rw-r-----  1  jose     user  0      Jun  5 18:32 /tmp/ctmB.BAAa001JC

MIPSPro C++ compiler:
I  c++_fe               02/26/99  C++ Front-end, 7.2.1

The command

% CC -c solvate.cc

produces the following tempfiles:

+  -rw-r-----  1  jose     user   86     Jun  5 18:30 /tmp/ctmL.AAAa001Ij
+  -rw-r-----  1  jose     user   0      Jun  5 18:30 /tmp/ctmB.BAAa001Ij

MIPSPro F77 compiler:
I  ftn77_fe             02/26/99  Fortran 77 Front-end, 7.2.1

% f77 -c readt.f

which produces the following tempfiles:

+  -rw-r-----  1  jose     user     0   Jun  5 18:27 /tmp/ctmL.AAAa001Hs
+  -rw-r-----  1  jose     user     0   Jun  5 18:27 /tmp/ctmB.BAAa001Hs

MIPSPro F90 compiler:
I  ftn90_fe             02/26/99  Fortran 90 Front-end, 7.2.1

% f90 -c real64.f

similarily yields the following tempfiles as it works:

+  -rw-r-----  1  jose     user   86     Jun  5 18:34 /tmp/ctmL.AAAa001JM
+  -rw-r-----  1  jose     user   0      Jun  5 18:34 /tmp/ctmB.BAAa001JM

And finally, if we invoke the compiler to compile a final binary, we see
the same behavior:

% cc -o temp-watch *.c

+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmL.AAAa001Jy
+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmB.BAAa001Jy
+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmL.CAAa001Jy
+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmB.DAAa001Jy
+  -rw-r-----  1  jose     user   93     Jun  5 18:37 /tmp/ctmL.EAAa001Jy
+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmB.FAAa001Jy
+  -rw-r-----  1  jose     user   88     Jun  5 18:37 /tmp/ctmL.GAAa001Jy
+  -rw-r-----  1  jose     user   0      Jun  5 18:37 /tmp/ctmB.HAAa001Jy

The lack of good randomness is readily observed if we do a series of
compiles generating object code (cc -c). Only the last two positions
change, the rest of it is predictable as a sunrise:

+  -rw-r-----  1  jose     user   0      Jun  5 18:42 /tmp/ctmL.AAAa001K9
+  -rw-r-----  1  jose     user   0      Jun  5 18:42 /tmp/ctmB.BAAa001K9
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001KT
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001KT
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001KX
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001KX
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Kd
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kd
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001K-
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001K-
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Ke
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Ke
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Kg
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kg
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001Kk
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kk
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Kn
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kn
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001Kt
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kt
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Kx
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Kx
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001Ku
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Ku
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001L9
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001L9
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001L3
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001L3
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001LB
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001LB
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001L2
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001L2
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001LF
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001LF
+  -rw-r-----  1  jose     user   89     Jun  5 18:43 /tmp/ctmL.AAAa001LJ
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001LJ
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001LO
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001LO
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmL.AAAa001Bv
+  -rw-r-----  1  jose     user   0      Jun  5 18:43 /tmp/ctmB.BAAa001Bv
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmL.AAAa001LT
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmB.BAAa001LT
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmL.AAAa001LP
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmB.BAAa001LP
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmL.AAAa001LU
+  -rw-r-----  1  jose     user   0      Jun  5 18:44 /tmp/ctmB.BAAa001LU

So, all of the major compilers, C, C++, F77 and F90, shipped in the
MIPSPro 7.2.1 distribution are affected by the issue.

What's the big deal? The issue in predictability is that we can abuse it.
The temporary files inherit the umask of the user who invokes the
commands, either cron or the compilers. Should this be set to being group
or, God help you, world writable, all sorts of nastiness can ensue.

In the case of compilers, we can append our code to the temporary files if
we were an attacker. Since we know what to expect, once we see a situation
ripe for the picking, we can slow the machine down and abuse the code that
is being compiled to our heart's content. The randomness, or entropy, in
the naming of the tempfiles is rather low, and as such is prone to abuse
by an attacker.

While not a "Hey neat, I got root!" exploit, this is easily part of a
larger attack. This can be abused to yield uid changes in some scenarios,
either from one unprivilidged uid to another or from an unprivilidged uid
to privilidged ones, including uid=0 (root).

I have to admit that this isn't rocket science or even very novel
thinking, but it bears pointing out.

-----------[ Acknowledgements:

Thanks to rabbit <rabbit () crimelabs com> for some helpful discussions on
this topic.


Current thread: