Hacking Linux Exposed





previous article
next article
The Hazards of Inconsistency
By Bri Hatch.

Summary: Linux's inconsistencies can open dangerous vulnerabilities when unsuspecting admins don't stay up to date on the latest news about their tools.

Linux's inner workings are occasionally inconsistent. This is not unique to Linux though. I want to cry, for example, every time I try to set up an LPR printer in Windows because each version or service pack moves things into completely different places. Of course, the fact that I'd be forced to touch a Windows machine in the first place could be the cause of my tears.

As to Linux's inconsistency, let's look at how 'chown' behaves. (Yes, you'll need to run these commands as root.)

# ls -l
-rwx------    1 root     root       100 Feb 28 12:00 realfile
lrwxrwxrwx    1 root     root         8 Feb 28 12:00 link -> realfile

# /bin/chown luser:luser link; ls -l
-rwx------    1 root     root       100 Feb 28 12:00 realfile
lrwxrwxrwx    1 luser    luser        8 Feb 28 12:00 link -> realfile

/bin/chown changed the owner of the link, not the file pointed to by the link. This may seem nice, but what happens if you do the same thing in a C program using the chown(2) system call instead?

  $ cat sys_chown.c

  #include <stdio.h>
  #include <sys/types.h>
  #include <unistd.h>
  main() {
      chown("link",443,443);   /* userid/groupid 443 is bob */
  /* END */

# make sys_chown
# ./sys_chown
# ls -l
-rwx------    1 bob      bob        100 Feb 28 12:00 realfile
lrwxrwxrwx    1 luser    luser        8 Feb 28 12:00 link -> realfile

So using C, the chown(2) system call ended up changing the ownership of realfile, not the symlink. What happened? Why did /bin/chown act differently than the chown(2) system call? Which one is 'right'?

The POSIX definition of chown acts as we see in the second example -- chown on a file modifies the owner/group of the target file, not the symlink. If you want to modify the symlink itself, you need to use the lchown(2) system call instead.

In fact, if you run 'chown luser:luser link' on a non-Linux system, such as Solaris, you'll see 'realfile' being changed in both cases. This behaviour is the POSIX standard. The logic behind Linux /bin/chown's use of lchown(2) escapes me. If you want to get true POSIX chown behaviour on Linux, you need to use 'chown -- dereference ...'

So let's look at a possible attack. On a non-Linux system, say a malicious user creates the following link in the Web DocumentRoot:

  -rw-rw-r--    1 baduser   baduser    12 Feb 28 12:00 blah.html -> /etc/passwd

Should root do a 'chown web:web /path/to/docroot' on this system, /etc/passwd will now be owned by the Web user. If baduser can get Web permissions (say he can write CGIs), then he can take over the system rather trivially. On non-Linux machines, you'd need to use 'chown -h ...' to make sure you affect the link itself, not the actual target file.

Why is this a security problem for Linux? Linux' /bin/chown by default affects the link, not the target file, which would seem to be a good thing in this case. Well, call it a pet peeve, but I don't like things that don't behave right. A Solaris admin must learn to use 'chown -h' to be secure and because of it, should he write something similar in C or Perl, he'll know to use the lchown(2) call. However, the Linux administrator, having been blissfully unaware of the difference, may end up falling into this symlink attack.

So what's my point? Make sure that you know the ins and outs of all your tools -- even things you take for granted -- when security is on the line. Try perusing man pages at least once a week for grins and see what new things you can discover, or misconceptions you can correct.

Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He has taught his daughter to say "POSIX Compliant" but I don't think she knows what it means. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2002.

This article was first published here in ITworld.com Inc., 118 Turnpike Rd., Southborough, MA 01772  on 02-Apr-2002.

previous article
next article