Bash和Root权限问题

时间:2015-10-07 06:41:14

标签: bash sh root

所以,我现在正在通过Ubuntu虚拟机中的安全实验室工作,我遇到了一个问题。指令有时可能有点模糊或不清楚。截至目前,我编写了一个运行ls。

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

然后我以名称lsBAK备份了/ bin / ls并删除了原始文件。我以ls的名义链接到我编译的程序,这样当我输入时,ls,这个程序将运行。它最终允许我在文件夹上运行ls我没有权限运行它,因为它具有root访问权限。最终促使我这样做的问题写成如下:“你能让这个Set-UID程序(由root拥有)运行代码而不是/ bin / ls吗?如果可以的话,你的代码是否以root权限运行?描述并解释你的观察结果。“

这一切都很好。现在我应该用bin / sh或/ bin / bash做同样的事情。

说明字面上说:“现在,更改/ bin / sh使其返回/ bin / bash,并重复上述攻击”

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

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

我尝试过./bash,bash等等。我目前拥有的是一个大致完全相同的程序,我正在进行以下系统调用:

system("bash");

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

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

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

2 个答案:

答案 0 :(得分:2)

以下是一些代码,可以帮助您了解以下一些苏格拉底式问题:

#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代替system-p的{​​{1}}选项有什么作用?

为什么会有声明:

bash
startup code of bash around line 496中的

?最后,这段代码是否与练习中的代码受到同样的攻击?

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

答案 1 :(得分:1)

实际上/ 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上,这将是正确的。事实上,只有少数操作系统使用bash作为默认系统shell,其中许多操作系统正在恢复为POSIX sh的almquist shell派生。

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

bash -c "ls"

或者例如:

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