Linux
在沒有原始碼的情況下隱藏程序的參數
我需要隱藏我正在執行的程序的一些敏感參數,但我無權訪問原始碼。我也在共享伺服器上執行它,所以我不能使用類似的東西,
hidepid
因為我沒有 sudo 權限。以下是我嘗試過的一些事情:
export SECRET=[my arguments]
,然後呼叫./program $SECRET
,但這似乎沒有幫助。./program
cat secret.txt``其中secret.txt
包含我的論點,但全能ps
者能夠嗅出我的秘密。有沒有其他方法可以隱藏不涉及管理員干預的論點?
正如這裡所解釋的,Linux 將程序的參數放在程序的數據空間中,並保留指向該區域開始的指針。這是
ps
等等用來查找和顯示程序參數的東西。由於數據在程序的空間中,它可以對其進行操作。在不更改程序本身的情況下執行此操作涉及載入一個帶有
main()
函式的 shim,該函式將在程序的真正 main 之前呼叫。這個 shim 可以將真正的參數複製到一個新的空間,然後覆蓋原始參數,以便ps
只看到 nuls。以下 C 程式碼執行此操作。
/* https://unix.stackexchange.com/a/403918/119298 * capture calls to a routine and replace with your code * gcc -Wall -O2 -fpic -shared -ldl -o shim_main.so shim_main.c * LD_PRELOAD=/.../shim_main.so theprogram theargs... */ #define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <dlfcn.h> typedef int (*pfi)(int, char **, char **); static pfi real_main; /* copy argv to new location */ char **copyargs(int argc, char** argv){ char **newargv = malloc((argc+1)*sizeof(*argv)); char *from,*to; int i,len; for(i = 0; i<argc; i++){ from = argv[i]; len = strlen(from)+1; to = malloc(len); memcpy(to,from,len); memset(from,'\0',len); /* zap old argv space */ newargv[i] = to; argv[i] = 0; } newargv[argc] = 0; return newargv; } static int mymain(int argc, char** argv, char** env) { fprintf(stderr, "main argc %d\n", argc); return real_main(argc, copyargs(argc,argv), env); } int __libc_start_main(pfi main, int argc, char **ubp_av, void (*init) (void), void (*fini)(void), void (*rtld_fini)(void), void (*stack_end)){ static int (*real___libc_start_main)() = NULL; if (!real___libc_start_main) { char *error; real___libc_start_main = dlsym(RTLD_NEXT, "__libc_start_main"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(1); } } real_main = main; return real___libc_start_main(mymain, argc, ubp_av, init, fini, rtld_fini, stack_end); }
無法干預
main()
,但您可以乾預標準 C 庫函式__libc_start_main
,該函式繼續呼叫 main。shim_main.c
按照開頭註釋中的說明編譯此文件,然後按所示執行它。我printf
在程式碼中留下了 a 以便您檢查它是否實際被呼叫。例如,執行LD_PRELOAD=/tmp/shim_main.so /bin/sleep 100
然後執行 a
ps
,您將看到一個空白命令和 args 正在顯示。命令 args 仍有一小段時間可見。為了避免這種情況,例如,您可以更改 shim 以從文件中讀取您的秘密並將其添加到傳遞給程序的 args 中。