9

隐藏与篡改Linux命令行参数

 3 years ago
source link: https://blog.csdn.net/dog250/article/details/115411814
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

隐藏与篡改Linux命令行参数

dog250 2021-04-03 08:31:10 4394
文章标签: linux

如果一个程序的命令行是一个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];

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

如果应用程序不可修改代码重新编译,有没有什么统一的办法呢?当然有,用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);
}
gcc -O2 -fPIC -shared -o libinject.so inject.c -ldl

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

// demo.c
#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:~# 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

浙江温州皮鞋湿,下雨进水不会胖。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK