clinuxsuid

A same suid + system program, different outputs on different systems


I write a simple program named suid.c:

int main(int argc, char* argv[]) {
        system(argv[1]);
}

Compile it with gcc then set suid permission (root user now):

# gcc suid.c -o suid
# chmod +s suid

I tried to run ./suid id with the www-data user on different virtual machines, but the output is different.

Why is that? Has anything changed in Linux?


Solution

  • It depends whether /bin/sh is bash or dash on your distribution. Bash always drops setuid/setgid privileges unless invoked with the option -p. Dash doesn't do anything special about privileges.

    On Ubuntu, the system function invokes sh, which is /bin/sh, which is dash, which doesn't drop privileges. On Kali, the system function invokes sh, which is /bin/sh, which is bash, which drops privileges. It's a matter of which shell the distribution installs as sh, not of how recent the distribution is.

    Bash's behavior can be a security countermeasure, but it isn't a very effective one. It's a second line of defense against misguided configurations or badly written programs that run with privileges that they shouldn't have, and allow untrusted input to functions such as system. However, such programs usually have other holes that allow the potential attacker to attack anyway, such as the ability to write to files.