任务 9:权限泄漏
Section outline
-
为了遵循最小权限原则,Set-UID 程序通常会在不再需要权限时永久放弃其 root 权限。此外,有时程序需要将控制权移交给用户,所以在交权之前,Set-UID 程序会放弃 root 权限。我们可以使用 Set-UID() 系统调用来撤销权限。Set-UID() 设置调用进程的有效用户 ID,但如果调用者的有效 UID 为 root,则实际 UID 和保存的 set-user-ID 也会被设置。因此,如果具有有效 UID=0 的 Set-UID 程序调用 Set-UID(N),则进程将成为普通进程,其所有 UID 都将被设置为 N。
在撤销权限时,一个常见的错误是权限泄漏。进程在仍具有权限时可能已经获得了一些特权功能。当权限被降级时,如果程序没有清除这些功能,它们可能仍然可以被非特权进程访问。换句话说,尽管进程的有效用户 ID 已变为非特权用户,但进程仍可能拥有特权。
编译以下程序,将其所有者更改为 root,并使其成为一个 Set-UID 程序。以普通用户身份运行该程序。你能利用该程序中的权限泄漏漏洞吗?你的目标是做到能够以普通用户的身份修改 /etc/zzz 文件。
void main() { int fd; char *v[2]; /* 假设 /etc/zzz 是一个重要的系统文件, * 并且它的所有者是 root,权限是 0644。 * 在运行此程序之前,你应先创建 /etc/zzz 文件。 */ fd = open("/etc/zzz", O_RDWR | O_APPEND); if (fd == -1) { printf("Cannot open /etc/zzz\n"); exit(0); } // 打印文件描述符值 printf("fd is %d\n", fd); // 通过将有效 uid 设置为与实际 uid 相同来永久放弃特权 setuid(getuid()); // 执行 /bin/sh v[0] = "/bin/sh"; v[1] = 0; execve(v[0], v, 0); }