请考虑以下代码:
char *args[3];
char *arg = "\x90\x90\x00\x90\x90";
args[0] = "/path/to/exe";
args[1] = arg;
args[2] = NULL;
execve(args[0], args, NULL);
由于arg
在中间终止为空,因此当execve创建新的过程映像时,不会复制\x00
以外的所有内容以用于新进程。有什么方法可以"技巧" execve复制\x00
以外的所有内容?
答案 0 :(得分:3)
简短的回答是否定的。 execve
(实际上,整个exec
系列)的参数是C字符串,因此,空字节终止。如果它没有停止在空字节,它将无法知道字符串的长度。出于同样的原因,任何可执行文件都不应期望argv
中的空字节。
答案 1 :(得分:2)
字符串的C约定是空终止,包括类似于execve的系统调用。
即使有可能绕过内核系统调用接口的执行填充程序,内核也无法将带有真正嵌入的nul字节的args支持到进程表中作为系统调用,库,工具和接口(例如procfs)即使有可能,流程管理也会显示截断的流程参数。
如果您有兴趣调用linux内核execve系统调用,请直接使用以下文章:http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html?m=1
一旦你阅读了那篇文章,你会发现execve api基本上是一个由nul终止的字符串数组,它被传递给它处理的内核。
TL; DR没有绕过它。
答案 2 :(得分:0)
一种技术是用一些其他字符(例如4个FF)替换null,假设连续4个FF永远不会成为数据的一部分。然后将它们替换回null。假设您可以修改被调用的exe。