Linux

在沒有原始碼的情況下隱藏程序的參數

  • November 14, 2017

我需要隱藏我正在執行的程序的一些敏感參數,但我無權訪問原始碼。我也在共享伺服器上執行它,所以我不能使用類似的東西,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 中。

引用自:https://unix.stackexchange.com/questions/403870