rh0*_*h0x 5 c execve shellcode
我必须填写以下参数:
int execve(const char *filename, char *const argv[], char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
如果我执行这个程序:
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/sh";
args[1] = NULL;
execve(args[0], args, NULL);
}
Run Code Online (Sandbox Code Playgroud)
shell 按预期正确生成。
我的问题是,如果我传递 NULL 作为第二个参数,shell 也会正确生成:
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/sh";
args[1] = NULL;
execve(args[0], NULL, NULL);
}
Run Code Online (Sandbox Code Playgroud)
那么使用 args 向量(带有“/bin/sh”+ NULL)作为第二个参数而不是 NULL 的目的是什么?
在这一行中:execve(args[0], NULL, NULL);您只是使用args数组的第一个元素。您也可以使用类似的东西char* command="/bin/sh"。你必须传递一些东西,因为这就是execve()定义的方式。在你的情况下你通过了NULL,因为你不需要通过任何东西。
第二个参数的要点execve()是将参数传递给您正在生成的命令。假设您只想执行而不是 shell ls,那么您可以传递以下参数:
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/ls";
args[1] = "-lh";
execve(args[0], args, NULL);
}
Run Code Online (Sandbox Code Playgroud)
另外,引用man execve:
argv 是传递给新程序的参数字符串数组。 按照约定,这些字符串中的第一个应该包含与正在执行的文件关联的文件名。envp 是一个字符串数组,通常采用 key=value 的形式,作为环境传递给新程序。
如果您传递一个空指针作为 的第二个或第三个参数execve,则根据 POSIX,您的程序是不正确的;这两个参数都必须为非空。(这并不是 的规范中明确说明的execve全部内容,但它就在那里。)我当前正在处理传递空指针的操作系统上键入此内容,
execve("executable", 0, 0);
Run Code Online (Sandbox Code Playgroud)
相当于传递空数组,例如
execve("executable", (char *[]){0}, (char *[]){0});
Run Code Online (Sandbox Code Playgroud)
但当我得知其他操作系统会引发分段错误或设置为 或 返回 -1 时,我并不errno感到EFAULT惊讶EINVAL。
允许为这些参数传递空数组,但如果第二个参数是空数组,新执行的程序将在argc/中接收零个参数,和/或如果第三个参数是空数组,则/中接收零个环境变量。许多程序在这些条件下都会发生故障。例如,很常见看到类似的事情argvenvpenviron
int main(int argc, char **argv)
{
if (argc != 4) {
fprintf(stderr, "usage: %s one two three\n", argv[0]);
return 2;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
其中程序隐式假设argv[0]始终为非空。
因此,您应该始终为两个参数提供非空数组。通常的惯例是,如果您没有其他事情可做,则可以使用
execve(program, (char *[]){program, 0}, environ);
Run Code Online (Sandbox Code Playgroud)
它提供程序自己的名称作为argv[0]并且没有其他参数,以及您从自己的父级获得的同一组环境变量。