简体   繁体   English

代码漏洞

[英]Code vulnerability

As a learning exercise, I am trying to find a weakness in the following code snippet to gain access as the owner of the executable. 作为一项学习练习,我试图在下面的代码片段中找到一个弱点,以便以可执行文件的所有者身份获得访问权限。

setresuid(geteuid(), geteuid(), geteuid());
system("/usr/bin/id");

FWIW, I can't see any. FWIW,我什么都看不到。 I know setresuid will set the uid to the owner of the file, but I can't change the owner to anyone but myself. 我知道setresuid会将uid设置为文件的所有者,但是我不能将所有者更改为除我之外的任何人。 I thought about trying to redirect the id command by altering the PATH, but since it uses an absolute path, that trick doesn't work. 我曾考虑过尝试通过更改PATH来重定向id命令,但是由于它使用了绝对路径,因此该技巧不起作用。 Hints? 提示?

It is possible to exploit an obscure (and now patched) issue involving the unchecked usage of setresuid() : 有可能利用一个晦涩(现已修补)的问题,该问题涉及对setresuid()的未经检查的使用:

  1. Under Linux 2.6 and later, setresuid() can fail if the process is running with an RLIMIT_NPROC (that is, a limit on the number of processes as set by ulimit -n ) such that the target UID would have too many processes if the setresuid() succeeded. 在Linux 2.6和更高版本中,如果进程使用RLIMIT_NPROC (即,对由ulimit -n设置的进程数的限制)运行,则setresuid()可能会失败 ,从而使得如果setresuid() ,目标UID会有太多进程setresuid()成功。

    However, under Linux 3.1 and later, failing a setresuid() sets a flag on a process such that any subsequent execve() calls will fail. 但是,在Linux 3.1和更高版本中,如果setresuid()失败, setresuid()在进程上设置一个标志,以使任何后续execve()调用都将失败。 This would prevent the system() from running on any modern Linux if the setresuid() failed. 如果setresuid()失败,这将阻止system()在任何现代Linux上运行。

  2. Unless there is some larger context which has been omitted, it may be possible to set environment variables (eg, LD_PRELOAD ) which cause code to be injected into /usr/bin/id . 除非有一些较大的上下文被忽略,否则可能会设置环境变量(例如LD_PRELOAD ),从而导致代码被注入到/usr/bin/id These variables are ignored for setuid executables, but will not be ignored for executables launched by a setuid executable, as is occurring here. 这些变量对于setuid可执行文件将被忽略,但对于setuid可执行文件启动可执行文件将不会被忽略,就像在这里发生的那样。

If you are on a vulnerable system (Linux 2.6 through 3.0), you may be able to exploit this vulnerability by setting environment variables and causing the setresuid() to fail, so that /usr/bin/id runs user-specified code as root. 如果您使用的是易受攻击的系统(Linux 2.6至3.0),则可以通过设置环境变量并导致setresuid()失败来利用此漏洞,以便/usr/bin/id以root用户/usr/bin/id运行用户指定的代码。

The system() function executes the command given as its argument by passing it to /bin/sh -c . system()函数通过将参数传递给/bin/sh -c来执行作为其参数给出的命令。 I think the /usr/bin/id program is not particularly relevant; 我认为/usr/bin/id程序不是特别重要; it is the shell's behavior that is key. 关键是外壳的行为。 In particular, note that the shell's startup behavior is different when the real and effective UIDs differ: 特别要注意的是,当实际UID和有效UID不同时,shell的启动行为也不同:

If the shell is started with the effective user (group) id not equal to the real user (group) id [...] no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. 如果shell以有效用户(组)ID不等于真实用户(组)ID的身份启动,则不会读取启动文件,也不会从环境,SHELLOPTS,BASHOPTS,CDPATH,和GLOBIGNORE变量(如果它们出现在环境中)将被忽略,并且有效用户ID设置为实际用户ID。

-- BASH 4.1 manual -BASH 4.1手册

In the event that a program containing the code you presented is installed suid, the code prevents the condition given in that paragraph from applying by setting real, effective, and saved UIDs all equal to the effective UID (which will be the UID of the owner of the executable). 如果包含您提供的代码的程序已安装suid,则该代码会通过设置所有等于有效UID(将是所有者的UID)的实际,有效和保存的UID来防止应用该段中给出的条件可执行文件)。

Exploits typically revolve around unsafe use of untrustworthy data, with environment variables being a frequent offender. 攻击通常围绕不安全地使用不可靠的数据,而环境变量常常是违法者。 The ENV environment variable in particular names a file that under some circumstances the shell will execute at startup. ENV环境变量特别命名一个文件,该文件在某些​​情况下将在启动时执行。 bash will not run it when the real and effective UIDs differ, as documented in the excerpt above, but otherwise will do so when invoked interactively in POSIX compatibility mode or as sh . 如上面摘录中所述,当实际UID与有效UID不同时, bash不会运行它,但在POSIX兼容模式下以交互方式或以sh调用时, bash不会运行它。

That doesn't help for non-interactive invocation, as applies here, so now I have to go speculative. 如此处适用的那样,这对于非交互式调用没有帮助,所以现在我不得不进行推测。 I suspect , but cannot currently document, that some other past -- and maybe even present -- versions of the shell do read and execute commands from the file named by ENV when invoked non-interactively. 怀疑 ,但目前无法记录,以非交互方式调用时,shell的其他某些版本(甚至可能是当前版本) 确实会ENV命名的文件中读取并执行命令。 That would provide a vector for executing arbitrary commands as the owner of the setuid program. 这将提供一个向量来作为setuid程序的所有者执行任意命令。

In weak support of that speculation I direct your attention to the BASH_ENV variable, which is analogous to ENV , but is used when bash is invoked non interactively, as bash . 在这种推测的弱支持下,我将您的注意力转向BASH_ENV变量,该变量类似于ENV ,但在交互调用bash时(如bash )使用该变量。 I am supposing that once these two variables were more parallel, applicable to both interactive and non-interactive modes, but the non-interactive use of ENV and the interactive use of BASH_ENV were removed at different times. 我假设一旦这两个变量更加并行,就适用于交互式和非交互式模式,但是在不同时间删除了ENV的非交互式使用和BASH_ENV的交互式使用。 for different reasons. 由于不同的原因。 Quite possibly the non-interactive use of ENV was removed to plug exactly the hole that you are looking for. 很可能删除了ENV的非交互式使用,以准确塞住您要查找的孔。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM