6

sudo is elevated to root upon launch because it's binary has a setuid enabled. But when I give /bin/login the exact privileges sudo has, and I try to run it from a user that isn't root, I get the error:

No utmp entry.  You must exec "login" from the lowest level "sh"

My first question is, what does that error mean? My second is, why does it work when I run sudo login from that same user? Besides using a setuuid to elevate to root, how else does sudo work? I've written a simple dash script at ~/root to run whoami and exit, but it returns the user name of my unprivileged user.

$ ls -l ./root /usr/bin/sudo
-rwsr-xr-x 1 root root     29 Jul 15 02:40 ./root
-rwsr-xr-x 1 root root 157760 Jan 10  2016 /usr/bin/sudo

$ ./root
unprivileged user

So I have three questions:

  1. What is the error I get with login?
  2. Why does login work with sudo?
  3. Why my simple script to run whoami doesn't work?
2
  • 1
    what OS are you using ? and can you post your script too ?
    – Rahul
    Jul 15, 2016 at 7:07
  • 1
    The error you are getting, is nothing to do with user and permissions. The error is about where you run login from. You need to find out what login does, and how to use it. Also if you setuid root programs you will end up with security problems, like users being able to become root. Gnu/Linux is not like Microsoft's windows — you do not have to turn of the security to be able to do anything. Jul 15, 2016 at 8:17

1 Answer 1

6

What is the error I get with login?

When searching trough the source code of login, we see this passage:

amroot = (getuid () == 0);
[...]
utent = get_current_utmp ();
/*
 * Be picky if run by normal users (possible if installed setuid
 * root), but not if run by root. This way it still allows logins
 * even if your getty is broken, or if something corrupts utmp,
 * but users must "exec login" which will use the existing utmp
 * entry (will not overwrite remote hostname).  --marekm
 */
if (!amroot && (NULL == utent)) {
     (void) puts (_("No utmp entry.  You must exec \"login\" from the lowest level \"sh\""));
     exit (1);
}

The interessting part is the if clause at the end. The error message appears when getuid() is not 0 and if there is no utmp entry. getuid() returns the real user ID of the calling process. If you invoke login with the setuid flag set, the real uid and effective uid differ. login is, as the comment in the source snippet suggest, "picky" in such cases: it fails and throws the mentioned error.


Why does login work with sudo?

sudo itself has the setuid bit set, thus euid and ruid differ. But, sudo executes the binary of login and sets both the real and the effective uid to the target user. It will therefore not fail anymore.


Why my simple script to run whoami doesn't work?

Your script has a shebang line (#!) in it (I assume). What happens is the following: the kernel opens the executable (in your case a text file) and observes a #!. Instead of the text file, the interpreter given in the shebang line is invoked (for example /bin/bash or /bin/sh) with the scripts name as first argument. Most unix and linux operating systems ignore the setuid bit when set on a script, because it is a security issue.

Imagine a script with setuid set. The attacker can then create a symbolic link to this script, invoke that script, and then change the symbolic link to his script, right before the interpreter opens the script behind the symbolic link (which is the evil one then).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .