ソースコードなしでプログラムパラメータを隠す

ソースコードなしでプログラムパラメータを隠す

実行中のプログラムの一部の機密パラメータを非表示にする必要がありますが、ソースコードにアクセスできません。私も共有サーバーで実行していますが、hidepidsudo権限がないので、それはできません。

私が試したいくつかのことは次のとおりです。

  • export SECRET=[my arguments]、そして電話をかけたが./program $SECRET役に立たないようです。

  • ./program `cat secret.txt`私の主張はそこにありますが、secret.txt全能の神はps私の秘密を見つけることができます。

管理者の介入なしに私の主張を隠す他の方法はありますか?

ベストアンサー1

説明どおりここ、Linuxはプログラムのパラメータをプログラムのデータスペースに入れ、その領域の先頭へのポインタを保持します。これはps、他の人がプログラムパラメータを見つけて表示するために使用する方法です。

データはプログラムスペースにあるため、これを操作できます。プログラム自体を変更せずにこれを行うには、main()プログラムの実際のメインルーチンの前に呼び出される関数を含むshimをロードする必要があります。このシムは実際のパラメータを新しいスペースにコピーし、psnull値のみが表示されるように元のパラメータを上書きします。

次の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を呼び出すmain()標準Cライブラリ関数を妨害する可能性があります。開始コメントに記載されているようにこのファイルをコンパイルし、指示に従って実行します。実際に呼び出されたことを確認できるようにコードを残しました。たとえば、次のようにします。__libc_start_mainshim_main.cprintf

LD_PRELOAD=/tmp/shim_main.so /bin/sleep 100

その後、aを実行するとps空のコマンドとパラメータが表示されます。

コマンドパラメータが表示されるまでにはまだ時間がかかります。これを回避するには、shimを変更してファイルからシークレットを読み取り、プログラムに渡されたパラメータに追加できます。

おすすめ記事