// 2. 检查是否以 root 权限运行 if (geteuid() == 0) { printf("\nRunning as ROOT (Privileged User)\n"); // 作为 root,可以设置为任意有效的 UID // 这里我们尝试设置为 'nobody' 用户 (通常 UID 65534, 但请检查你的系统) target_uid = 65534; printf("Attempting to set UID to %d (usually 'nobody' user)...\n", target_uid);
print_current_uids("Before setuid"); result = setuid(target_uid); if (result == 0) { printf("setuid(%d) succeeded.\n", target_uid); print_current_uids("After setuid"); printf("Note: All UIDs (Real, Effective, Saved) are now %d.\n", target_uid); printf("The process is now running with 'nobody' privileges.\n"); } else { perror("setuid"); printf("Failed to set UID to %d.\n", target_uid); }
} else { printf("\nRunning as a REGULAR USER (UID: %d)\n", getuid());
// 作为普通用户,只能设置为自己的 ruid 或 suid target_uid = original_ruid; // 选择设置为自己的真实 UID (这不会改变任何东西) printf("Attempting to set UID to my Real UID (%d)...\n", target_uid); print_current_uids("Before setuid"); result = setuid(target_uid); if (result == 0) { printf("setuid(%d) succeeded (as expected).\n", target_uid); print_current_uids("After setuid"); } else { perror("setuid"); }
// 尝试设置为一个无效的 UID (比如一个不存在的或不属于我的 UID) // 这通常会失败 target_uid = 9999; // 假设这是一个无效的或不属于当前用户的 UID printf("\nAttempting to set UID to an invalid/different UID (%d)...\n", target_uid); result = setuid(target_uid); if (result == -1) { if (errno == EPERM) { printf("setuid(%d) failed with EPERM (Operation not permitted) - as expected for a regular user.\n", target_uid); printf("This is because %d is not my Real UID (%d) or Saved Set-UID (%d).\n", target_uid, original_ruid, original_suid); } else { perror("setuid"); } print_current_uids("After failed setuid"); } else { printf("setuid(%d) unexpectedly succeeded.\n", target_uid); print_current_uids("After unexpected setuid"); } }
printf("\n--- Summary ---\n"); printf("The setuid() function changes the Effective UID of the process.\n"); printf("For root: It can change to any UID, and also changes Real and Saved UID.\n"); printf("For regular users: It can only change Effective UID to Real or Saved UID.\n"); printf("This is crucial for security, especially in programs like setuid binaries.\n");
Running as a REGULAR USER (UID: 1000) Attempting to set UID to my Real UID (1000)... [Before setuid] Current UIDs - Real: 1000, Effective: 1000, Saved: 1000 setuid(1000) succeeded (as expected). [After setuid] Current UIDs - Real: 1000, Effective: 1000, Saved: 1000
Attempting to set UID to an invalid/different UID (9999)... setuid(9999) failed with EPERM (Operation not permitted) - as expected for a regular user. This is because 9999 is not my Real UID (1000) or Saved Set-UID (1000). [After failed setuid] Current UIDs - Real: 1000, Effective: 1000, Saved: 1000
--- Summary --- The setuid() function changes the Effective UID of the process. For root: It can change to any UID, and also changes Real and Saved UID. For regular users: It can only change Effective UID to Real or Saved UID. This is crucial for security, especially in programs like setuid binaries.
Running as ROOT (Privileged User) Attempting to set UID to 65534 (usually 'nobody' user)... [Before setuid] Current UIDs - Real: 0, Effective: 0, Saved: 0 setuid(65534) succeeded. [After setuid] Current UIDs - Real: 65534, Effective: 65534, Saved: 65534 Note: All UIDs (Real, Effective, Saved) are now 65534. The process is now running with 'nobody' privileges.