【发布时间】:2019-07-16 02:42:09
【问题描述】:
如何在execl() 之后隐藏/更改进程参数?或者我们如何隐藏/更改使用 system() / execl() 的子进程的参数?
在SHC 上工作(此应用程序的目的是将bash 脚本编译成二进制文件)我正在使用execl() 函数来执行sh 脚本;问题是execl() 参数暴露给ps;这个问题的目的是让SHC更可靠一点,并解决用户报告的一些问题。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc,char* argv[]){
int runThis;
//Create child process
if(fork() == 0){
printf("I'm the child\n");
//runThis = system("echo test; sleep 30");
runThis = execl("/bin/sh", "sh", "-c", "echo test; sleep 30", (char *) 0);
exit(0);
} else {
printf("I'm the parent.\n");
}
printf("Continue main\n");
return 0;
}
运行此代码时,sh -c echo test; sleep 30 暴露给 ps
解决方案尝试1:成功但不可靠
使用ld_preload 隐藏命令参数可以使用此solution 或使用setenv("LD_PRELOAD","myLib.so",1);(dlopen() 不适用于execl()),此解决方案确实需要将库加载到我们的应用程序。
解决方案尝试 2:半成功
用ld --wrap=symbol 包装__libc_start_main,这适用于父级,但代码在execl() / system() 之后没有包装
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
int __real___libc_start_main(int (*main) (int, char **, char **), int argc, char **ubp_av, void (*init) (void), void (*fini)(void), void (*rtld_fini)(void), void (*stack_end));
int __wrap___libc_start_main(int (*main) (int, char **, char **), int argc, char **ubp_av, void (*init) (void), void (*fini)(void), void (*rtld_fini)(void), void (*stack_end)) {
printf("Main called\n");
//ubp_av[1] = "test";
int result = __real___libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end);
return result;
}
构建命令:(wrap.c 是上面的代码,example.c 是第一个代码示例)
gcc -c example.c -o 1.o;
gcc -c wrap.c -o 2.o;
gcc -Wl,-wrap,__libc_start_main -Wl,-wrap=__libc_start_main 1.o 2.o -o myapp
解决方案尝试 3:半成功
类似于尝试 2,它包括在构建时链接尝试 1 的代码...但这不适用于 execl()
- 将库构建为 libfoo 或其他名称
gcc -Wall -O2 -fpic -shared -Wl,-soname,libfoo.so -ldl -o libfoo.so wrap.c(wrap.c 是尝试 1 中的代码) - 安装它
sudo ln -s /path/libfoo.so /usr/lib64/libfoo.so - 链接
gcc example.c -o myapp -L.. -lfoo
解决方案尝试 4:相关但在这里没有用处
【问题讨论】:
-
你为什么要隐藏它们?没有无种族的方法可以做到这一点,但这听起来像是一个 XY 问题......
-
shc 并不是要完全隐藏 bash 内容(不可能),但至少很难发现转换后的脚本,这就是为什么我想从 ps 中隐藏它
-
这是不可能的。用过
strace吗?此外,您所要求的实际上与恶意软件接壤,因此如果它不是恶意的,您可能应该澄清您在做什么。寻求帮助开发恶意软件通常是题外话。 -
那么,您想分发在其他人的计算机上运行的东西,完全在他们的控制之下,并且您想对他们隐藏它的作用?那是行不通的。
-
无关紧要。因为不难。它仍在其他人的计算机上运行,完全由他们控制。而且没有办法混淆你的代码实际上做了什么,因为它做到了。读/写文件?很明显,没有办法混淆。在这种情况下,正如@R.. 已经发布的那样,有很多方法可以获取命令行参数。击败你的 LD_PRELOAD 黑客是微不足道的,而 also being completely unnecessary to defeat in the first place.