How to hide and tamper with Linux command line parameters? If the command line of a program is an inconvenient string such as password, how to prevent ps from printing it?
Hide and tamper with Linux command line parameters
ps is the command line taken from /proc/$pid/cmdline, and /proc/$pid/cmdline is the data obtained by parsing the stack area of the user program in the kernel space, then the answer is simple, just cover this area Yes, here is an example:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { char orig[16]; // Get the command line on the stack strcpy(orig, argv[1]); // Overwrite the command line on stack as soon as the command line is obtained strcpy(argv[1], "skinshoe"); getchar(); }
Hide and tamper with Linux command line parameters
If the application cannot be modified and re-compiled, is there any unified way? Of course, it is very convenient to use LD_PRELOAD:
// inject.c #define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int (*_main) (int, char * *, char * *); static int pixie_main(int argc, char **argv, char **env) { char tmp[16]; strcpy(tmp, argv[1]); strncpy(argv[1], "pixie", strlen(argv[1])); argv[1] = tmp; return _main(argc, argv, env); } int (*orig_start_main)(int (*main)(int, char **, char **), int argc, char **argv, void (*init) (void), void (*fini) (void), void (*_fini) (void), void (*stack_end)); int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, void (*init)(void), void (*fini)(void), void (*_fini)(void), void (*stack_end)) { orig_start_main = dlsym(RTLD_NEXT, "__libc_start_main"); _main = main; return orig_start_main(pixie_main, argc, argv, init, fini, _fini, stack_end); }
Hide and tamper with Linux command line parameters
Compile it:
gcc -O2 -fPIC -shared -o libinject.so inject.c -ldl
The following is an “existing program that cannot be changed”:
// demo.c #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { printf("%s\n", argv[1]); getchar(); }
Hide and tamper with Linux command line parameters
Hide and tamper with Linux command line parameters
Execute it with LD_PRELOAD:
LD_PRELOAD=./libinject.so ./demo 12345
At this point, the demo program still prints 12345, and ps sees pixie.
Just deploy LD_PRELOAD to the path. This is the standard method of hijacking a library.
Everything is a double-edged sword. If you can do good things, you can do bad things. With the above trick, you can actually modify the command line of any program at will:
int (*_main) (int, char * *, char * *); static int pixie_main(int argc, char **argv, char **env) { argv[1] = "pixie"; return _main(argc, argv, env); }
Try it out:
root@zhaoya-VirtualBox:~# LD_PRELOAD=./libinject.so ls -a ls: cannot access 'pixie': No such file or directory root@zhaoya-VirtualBox:~# LD_PRELOAD=./libinject.so /bin/echo hello pixie