如果一个程序的命令行是一个password之类的不便展示的字符串,如何不让ps打印出来呢?
ps是从/proc/$pid/cmdline里拿的命令行,而/proc/$pid/cmdline则是在内核空间解析用户程序的stack区域获取的数据,那么答案很简单,只需要覆盖掉这个区域即可,下面是个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( int argc, char * * argv)
{
char orig[ 16 ] ;
strcpy ( orig, argv[ 1 ] ) ;
strcpy ( argv[ 1 ] , "skinshoe" ) ;
getchar ( ) ;
}
如果应用程序不可修改代码重新编译,有没有什么统一的办法呢?当然有,用LD_PRELOAD很方便:
#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) ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
编译之:
gcc -O2 -fPIC -shared -o libinject.so inject.c -ldl
下面是一个“不能改的现有程序”:
#include <stdio.h>
#include <stdlib.h>
int main ( int argc, 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 * *) ;
static int pixie_main( int argc, char **argv, char **env)
{
argv[ 1] = "pixie" ;
return _main( argc, argv, env) ;
}
试试看:
root@zhaoya-VirtualBox:~
ls: cannot access 'pixie' : No such file or directory
root@zhaoya-VirtualBox:~
pixie
浙江温州皮鞋湿,下雨进水不会胖。