Bash 和根权限问题

Bash and Root Privilege Issues

所以,我目前正在 Ubuntu 虚拟机中完成安全实验室工作,我 运行 遇到了一个问题。说明有时可能有点含糊或不清楚。截至目前,我编写了一个 运行s ls.

的小 C 程序
#include <stdio.h>
int main()
{
    system("lsBAK -la");
    return 0;
}

然后我用名称 lsBAK 备份了 /bin/ls 并删除了原来的。我在名为 ls 的编译程序中创建了一个 link,这样当我键入 ls 时,该程序将改为 运行。它最终允许我 运行 ls 在我不应该 运行 的文件夹上,因为它具有 root 访问权限。最终促使我这样做的问题是这样写的:"Can you let this Set-UID program (owned by root) run your code instead of /bin/ls? If you can, is your code running with the root privilege? Describe and explain your observations."

这一切都很好。现在我应该对 bin/sh 或 /bin/bash.

做同样的事情

说明字面意思是:"Now, change /bin/sh so it points back to /bin/bash, and repeat the above attack"

我在同一个程序上尝试了很多变体。我似乎没有得到的是如何 运行 bash。如果我在终端中输入 sh,我会立即进入 shell。如果我键入 bash,什么也不会发生,即使 sh 是指向 bash 的 link。看起来它实际上可能正在打开一个 shell,但它看起来完全一样,而当我 运行 sh 我得到一个明显不同的 shell 来玩它显示 sh-4.3#而不是通常的 root@.... 运行ning sh 怎么可能给我一个不同于 运行ning bash 的结果,而 sh 只是一个 link到 bash?我错过了什么?

我的意思是,当我重新创建 sh 时,我只是 运行ning: ln -s bash sh

我已经尝试过 ./bash、bash 等。我目前拥有的是一个几乎相同的程序,我正在执行以下系统调用:

system("bash");

我删除了 sh 并在名称 sh 下为我的新程序 shUID 创建了一个 link。所以,我想应该发生的是,当我 运行 sh 时,它 运行 是我的程序 shUID,它执行系统调用。每当我 运行 sh 时,终端就会锁定,直到我按下 ctrl+C。

所以我显然是在寻找我在这里遗漏的任何东西。我假设我正确地回答了之前涉及 ls 的问题,但我似乎无法弄清楚这里发生了什么。感谢帮助。

编辑:我现在在实验室继续前进,发现 system() 实际上调用了 /bin/sh,所以我的问题似乎是如果我要替换它并依赖系统调用,这里有问题。我目前不确定如何处理这些信息,但它给了我一些方向。我仍然很感激帮助,但我很快就会使用这些新信息。

这里有一些代码可以帮助您了解以下苏格拉底式问题的情况:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int
main(int argc, char **argv)
{
    int i;
    printf("uid %d gid %d euid %d egid %d\n", getuid(), getgid(),
        geteuid(), getegid());

    printf("argc %d\n", argc);
    for(i = 0; i < argc; i++)
        printf("%d: %s\n", i, argv[i]);

    if (argc >= 2 && (argv[1][0] != '/')) {
        fprintf(stderr, "missing initial slash\n");
        return 2;
    }

    if (execv(argv[1], argv+1)) {
        perror("execve");
        return 1;
    } 
    return 0;
}

什么是UID,什么是EUID?为什么要检查 运行 文件的绝对路径名?为什么我使用 execv 而不是 systembash-p 选项有什么作用?

为什么会有这样的说法:

if (running_setuid && privileged_mode == 0)
    disable_priv_mode ();

startup code of bash around line 496?最后,这段代码是否与您练习中的代码受到相同的攻击?

我没有显示此代码的编译步骤,因为如果您不知道它的作用,则不应该构建它。

事实上 /bin/sh 在大多数系统上不仅仅是 bash 的符号链接。观察:

#include <stdio.h>
int main()
{
    /* if we were using bash this would not fail */
    system("type history");
    return 0;
}

尽管此代码段将环境变量 $SHELL 报告为 bash,但它确实不是我们正在使用的 shell:(阅读:这可能会引起混淆)

#include <stdio.h>
int main()
{
    system("echo $SHELL");
    return 0;
}

在 Debian、FreeBSD、NetBSD 和 Ubuntu 这将适用。事实上,只有少数 OS 正在使用 bash 作为默认系统 shell,并且其中许多正在恢复为 P[=31= 的 almquist shell 导数]IX sh.

如果您想使用 system() 中的 bash,您可能会发现以下命令很有用:

bash -c "ls"

或者例如:

#include <stdio.h>
int main()
{
    system("bash -c 'type history'");
    return 0;
}