How to hide and tamper with Linux command line parameters

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?

How to hide and tamper with Linux command line parameters
How to hide and tamper with Linux command line parameters

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
How to hide and tamper with Linux command line parameters
How to hide and tamper with Linux command line parameters

Leave a Comment