在Linux下想隐藏用户名或密码的话,如何操作?

时间:2021-04-16 14:43:48 作者: MM

有时候会遇到这样的需求,不希望命令行的某些参数被ps出来,比如命令行参数里可能存在一些用户名和密码之类的东西,在Linux下如果你想隐藏这些东西的话,你该如何操作?

如果一个程序的命令行是一个password之类的不便展示的字符串,如何不让ps打印出来呢?

ps是从/proc/$pid/cmdline里拿的命令行,而/proc/$pid/cmdline则是在内核空间解析用户程序的stack区域获取的数据,那么答案很简单,只需要覆盖掉这个区域即可,下面是个示例:

# include  # include  # include

intmain( intargc, char**argv) {charorig[ 16];

// 获取stack上的命令行strcpy(orig, argv[ 1]); // 获取命令行之后第一时间覆盖stack上的命令行strcpy(argv[ 1], "skinshoe"); getchar;}

如果应用程序不可修改代码重新编译,有没有什么统一的办法呢?当然有,用LD_PRELOAD很方便:

// inject.c# define_GNU_SOURCE # include  # include # include # include

int(*_main) ( int, char* *, char* *); staticintpixie_main( intargc, char**argv, char**env) {chartmp[ 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**), intargc, char**argv, void(*init) ( void), void(*fini) ( void), void(*_fini) ( void), void(*stack_end));

int__libc_start_main( int(*main)( int, char**, char**), intargc, 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;returnorig_start_main(pixie_main, argc, argv, init, fini, _fini, stack_end); }

编译之:

gcc-O2-fPIC-shared-olibinject.soinject.c-ldl

下面是一个“不能改的现有程序”:

// demo.c# include # include

intmain( intargc, char**argv) {printf( "%s\n", argv[ 1]); getchar;}

用LD_PRELOAD执行之:

LD_PRELOAD=./libinject.so ./demo 12345

此时,demo程序打印的依然是12345,然后ps看到的就是pixie了。

把LD_PRELOAD部署到路径里就好了。这是劫库的标准手法。

事事都是双刃剑,能做好事就能做坏事,用上面的把戏其实是可以任意修改任意程序的命令行的:

int(*_main) ( int, char* *, char* *); staticintpixie_main( intargc, char**argv, char**env ) {argv[ 1] = "pixie"; return_main(argc, argv, env); }

试试看:

root@zhaoya-VirtualBox:~ # LD_PRELOAD=./libinject.so ls -als: cannot access 'pixie': No such file ordirectory root@zhaoya-VirtualBox:~ # LD_PRELOAD=./libinject.so /bin/echo hellopixie

相关推荐
AI桌面浏览器

热文推荐

  • 48小时热文
  • 每周热文

在Linux下想隐藏用户名或密码的话,如何操作?