【问题标题】:Is it legal to pass a null program argument vector to execve()?将空程序参数向量传递给 execve() 是否合法?
【发布时间】:2018-01-07 20:44:12
【问题描述】:

考虑以下 C 代码 (x86_64)

#include <unistd.h>
int main()
{
    execve("/bin/ls", 0, 0);
}

我编译为gcc a.c并执行;我收到了 SIGABRT 错误

A NULL argv[0] was passed through an exec system call.  
Aborted

接下来在gdb上运行,一开始我也得到了SIGABRT,但是我第二次运行它并且成功了!

Starting program: /bin/ls 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

为什么?


我测试了/bin/sh,发现它总是与 *argv[] = NULL 一起工作...
我再次编写了一些可执行文件(不需要任何参数)来测试并发现它们都可以工作。

所以我猜只有/bin/sh 或其他shell 可以将*argv[] 设置为NULL,其他文件(如/bin/ls)会失败或行为异常。

【问题讨论】:

  • 阅读linux.die.net/man/2/execve,看看它需要什么参数。
  • 是的,我知道它是 UB 以及参数 execve() 所期望的,但是有没有办法弄清楚它为什么起作用,或者只是运气。我正在解决一些安全挑战,如果我能找出它的工作原理,这可能对我的 shellcode 有很大的改进。
  • @poming 你在运行什么操作系统?

标签: c linux gdb exec system-calls


【解决方案1】:

execve() 系统调用的手册页显示

argvenvp 数组必须各自在数组末尾包含一个空指针。

如果您的程序不符合这些要求,则无法确定从那时起事情的进展情况。如果它对某些程序“有效”,那只是运气不好。


手册页还说

按照惯例,这些字符串中的第一个(即argv[0])应该包含与正在执行的文件关联的文件名。

该约定相当严格(由 POSIX 强制执行),因此不这样做的程序可能被视为有缺陷。如果您要依赖argv[0],那么您的main() 测试它是否被正确调用可能是一个好主意,这样您可能会因错误消息而不是错误而失败,但并非所有程序都这样做。

【讨论】:

【解决方案2】:

Linux 专门将 argv=NULLenvp=NULL 视为有效的空列表,而不是返回 -EFAULT1。这记录在手册页中:
https://man7.org/linux/man-pages/man2/execve.2.html#NOTES

这是 POSIX 保证的;其他一些操作系统以这种方式工作,但有些则不然。

注意 1:(或者如果通过 libc 包装器,返回 -1 并设置 errno = EFAULT)。

这在 shellcode 中很常见,因为它已经是不可移植的,并且它将机器代码字节保存在有效负载中。 (或者作为ROP攻击的一部分你必须构建的东西)。但否则这是一个非常糟糕的主意。 Linux 手册页强烈建议不要使用它,只是出于可移植性的原因;它实际上保证可以在 Linux 上运行。 (execve 本身;被调用的程序可能不高兴找到argc=0argv[0] == NULL,以及一个空的环境。)


/bin/sh 这样的实际shell do 如果以这种方式调用,则可以工作,这也是为什么shellcode 可以不构造char*{"/bin/sh", NULL} 数组并传递指针的另一部分原因到那个。

正如 Toby 解释的那样,/bin/ls 在这种情况下出手并不完全令人惊讶。即使您使用execve("/bin/sh", (char*[]){NULL}, (char*[]){NULL}); 来便携地使用 execve,您仍然会像在 Linux 下一样使用argc=0 启动程序。

TL:DR:除非它是某些代码大小的一部分或其他不按正常方式执行的骇人听闻的原因,否则不要这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-20
    • 1970-01-01
    相关资源
    最近更新 更多