As per my understanding,
- RUID: uid of the caller of the process is called real uid.
- EUID: effective uid means allowed privilege for that process.
// setuid_file.c #include<stdio.h> int main(void) { int uid; uid=getuid(); printf("RUID : getuid() : %d\n",uid); uid=geteuid(); printf("EUID : geteuid() : %d\n",uid); system("whoami"); system("cat /etc/sudoers"); //only root user can access. here we can write any command which only root user can execute. } gcc setuid_file.c -o euid_zero chmod ug+s euid_zero So, on root terminal, I have set suid and guid for the euid_zero executable. Now, ff I try to run the executable using normal user, then below is the output.
ll euid_zero -rwsr-sr-x 1 root root 16768 Dec 30 00:59 euid_zero whoami kali id uid=1000(kali) gid=1000(kali) groups=1000(kali) ./euid_zero RUID : getuid() : 1000 EUID : geteuid() : 0 kali cat: /etc/sudoers: Permission denied So, here EUID is zero then also we can not gain root privilege. So, that means we have access privilege according to RUID, then what is the meaning of EUID if there is no use of EUID?
2 Answers
It allows the process to temporarily raise and lower privileges as it needs.
For example, a file-server daemon (smbd, ftpd) starts as root, but then seteuid()'s to the logged-in user's EUID. Now it can run most of the time with the logged-in user's EUID, letting the kernel apply file access checks, but still be able to raise its privileges back to EUID 0 for certain operations.
But note that when you use system(), this invokes the command through /bin/sh, and the Bash shell deliberately drops privileges whenever it detects an UID/EUID mismatch. Your own setuid process could in fact open /etc/shadow just fine – it's only tools launched through system() that won't be able to.
If you replace all system() calls with fork+exec, or even a simple open("/etc/shadow", O_RDONLY), you will see that having RUID=1000 but EUID=0 allows you to access the file. (Additionally, you will also see id reporting both sets of UID/GID.)
In general EUID itself works as you expect, the "problem" here is with system(3) and sh it uses. See the manual (man 3 system):
system()will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which/bin/shisbashversion 2: as a security measure,bash2 drops privileges on startup. (Debian uses a different shell,dash(1), which does not do this when invoked assh.)
It turns out the manual is not up-to-date. Nowadays dash behaves like bash. Frankly, I don't know what shell your OS uses as sh (you tagged ubuntu, Ubuntu uses dash; but kali in your question may suggest Kali, I'm not sure what Kali uses). Check with ls -l /bin/sh, it's probably dash. Regardless what it is, it most likely drops privileges and this is the reason of Permission denied you observed.
Even if your sh didn't drop privileges, system() wouldn't be a good idea. The already linked manual explicitly disadvises it:
Do not use
system()from a privileged program (a set-user-ID or set-group-ID program, or a program with capabilities) because strange values for some environment variables might be used to subvert system integrity.