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
而不是 system
? bash
的 -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;
}
所以,我目前正在 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
而不是 system
? bash
的 -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;
}