GNU/Linux >> Belajar Linux >  >> Linux

Sembunyikan argumen untuk memprogram tanpa kode sumber

Seperti yang dijelaskan di sini, Linux meletakkan argumen program di ruang data program, dan menyimpan pointer ke awal area ini. Inilah yang digunakan oleh ps dan seterusnya untuk menemukan dan menampilkan argumen program.

Karena data berada di ruang program, ia dapat memanipulasinya. Melakukan hal ini tanpa mengubah program itu sendiri berarti memuat shim dengan main() fungsi yang akan dipanggil sebelum main sebenarnya dari program. Shim ini dapat menyalin argumen sebenarnya ke ruang baru, lalu menimpa argumen asli sehingga ps hanya akan melihat nol.

Kode C berikut melakukan ini.

/* 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);
}

Tidak mungkin mengintervensi main() , tetapi Anda dapat mengintervensi fungsi pustaka C standar __libc_start_main , yang kemudian memanggil main. Kompilasi file ini shim_main.c seperti yang tercantum dalam komentar di awal, dan jalankan seperti yang ditunjukkan. Saya telah meninggalkan printf dalam kode sehingga Anda memeriksa apakah itu benar-benar dipanggil. Misalnya, jalankan

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

lalu lakukan ps dan Anda akan melihat perintah kosong dan argumen ditampilkan.

Masih ada sedikit waktu agar perintah args dapat terlihat. Untuk menghindarinya, Anda dapat, misalnya, mengubah shim untuk membaca rahasia Anda dari file dan menambahkannya ke argumen yang diteruskan ke program.


  1. Baca dokumentasi antarmuka baris perintah dari aplikasi yang dimaksud. Mungkin ada opsi untuk memberikan rahasia dari file alih-alih sebagai argumen secara langsung.

  2. Jika gagal, laporkan laporan bug terhadap aplikasi dengan alasan tidak ada cara yang aman untuk memberikan rahasianya.

  3. Anda selalu dapat dengan hati-hati(!) Menyesuaikan solusi dalam jawaban meuh dengan kebutuhan spesifik Anda. Berikan perhatian khusus pada komentar Stephane dan tindak lanjutnya.


Jika Anda perlu meneruskan argumen ke program untuk membuatnya berfungsi, Anda akan kurang beruntung apa pun yang Anda lakukan jika Anda tidak dapat menggunakan hidepid pada procfs.

Karena Anda menyebutkan ini adalah skrip bash, Anda seharusnya sudah memiliki kode sumbernya, karena bash bukan bahasa yang dikompilasi.

Jika gagal, Anda dapat dapat menulis ulang cmdline proses menggunakan gdb atau serupa dan bermain-main dengan argc /argv setelah itu sudah dimulai, tetapi:

  1. Ini tidak aman, karena Anda masih mengekspos argumen program Anda terlebih dahulu sebelum mengubahnya
  2. Ini cukup meretas, bahkan jika Anda bisa membuatnya berfungsi, saya tidak akan merekomendasikan untuk mengandalkannya

Saya benar-benar hanya merekomendasikan mendapatkan kode sumber, atau berbicara dengan vendor untuk memodifikasi kode. Memberikan rahasia pada baris perintah di sistem operasi POSIX tidak kompatibel dengan operasi aman.


Linux
  1. 5 Repositori Kode Sumber Teratas

  2. Cara Instal phpMyAdmin di Linux menggunakan Source Code

  3. Kode Sumber Netstat?

  1. Dapatkan Kode Sumber untuk Perintah Linux apa pun

  2. Contoh C argc dan argv untuk Mengurai Argumen Baris Perintah

  3. Di mana Kode Penjadwal CFS Linux?

  1. Bagaimana cara meneruskan argumen ke skrip yang dipanggil oleh perintah sumber?

  2. Nomor baris sumber dalam grafik panggilan perf?

  3. Pembaruan kernel tanpa me-reboot