-
-
[旧帖] [原创]Linux bin进程感染 0.00雪花
-
发表于: 2016-3-19 20:42 1976
-
曾经逆过一个应用,核心逻辑在run 这是bin进程运行,run进程与主进程通信。run进程由 exec bin进程启动的。exec进程是由主进程启动的。当时需要对run这个进程进行hook,所以使用LD_PRELOAD hook经exec对run进程感染,hook run进程。在此分享一下,有错误的地方感谢指出。
先给咱小白兄弟们引下路,篇幅问题想了解更多关于PRELOAD hook麻烦移步到google。loader加载会把LD_PRELOAD 指向so中的符号覆盖相同符号名的符号,用自己的函数替换系统库的函数,实现PRELOAD hook。
本次分享由4个c文件组成。exec 负责启动第一个bin 并指定LD_PRELOAD 参数为libmyfopen.so 这个so 中实现了两个函数,fopen() 与execve()。这两个函数定义与libc的fopen() 与execve()函数一样。所以系统再加载libc.so 时导出符号表fope()n与execve()就被libmyfopen.so这两个函数占了。run只负责启动run1。因为run的evecve()已经被hook,run调用execve()启动run1时,run1的fopen() 与execve()也被hook了。这些变化能从log输出看出来。
以下代码:
首先是exec.c //负责启动run 这个bin,并把自己的so 指定为LD_PRELOAD 参数。
#include <stdio.h>
#include <unistd.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv) {
char preload_lib[50];
sprintf(preload_lib, "LD_PRELOAD=%s", argv[1]);
LOGI("LD_PRELOAD=%s",argv[1]);
char * const args[] = { "./run", NULL };
char * const envs[] = { preload_lib, NULL };
execve("./run", args, envs);
LOGI("ex done.");
return 0;
}
然后是run.c //第一个bin 这个bin启动第二个bin
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include<unistd.h>
#include<sys/types.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv)
{
FILE * handler = fopen("/data/local/tmp/run","r");
if(handler != NULL){
LOGI("run %s\n",getenv("LD_PRELOAD"));
}
char *const args[] = {"./run1",NULL};
execve("./run1",args,NULL);
LOGI("run done.");
return 0;
}
最后是run1.c 这个bin
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include<unistd.h>
#include<sys/types.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv)
{
FILE * handler = fopen("/data/local/tmp/run1","r");
printf("run1 done.");
LOGI("run1 done.");
return 0;
}
再看一下preload so. myfopen.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
FILE * fopen(const char * path, const char * mode) {
if (path == NULL || strlen(path) == 0) {
LOGI("preload hook fopen path is NULL");
return NULL ;
}
LOGI("preload hook fopen path: %s mode: %s", path, mode);
FILE * (*FOPEN_FUNC)(const char * path, const char * mode) = NULL;
void *handle;
char *error;
FILE *ret;
//打开动态链接库
handle = dlopen(LIB_PATH, RTLD_LAZY);
if (!handle) {
LOGI("can not dlopen /system/lib/libc.so");
fprintf(stderr, "%s\n", dlerror());
}
//清除之前存在的错误
dlerror();
//获取一个函数
FOPEN_FUNC = dlsym(handle, "fopen");
if ((error = dlerror()) != NULL) {
LOGI("can not dlsym fopen");
fprintf(stderr, "%s\n", error);
}
//用原来的参数运行
ret = (*FOPEN_FUNC)(path, mode);
//关闭动态链接库
dlclose(handle);
return ret;
}
//---------------------hook exec----------------------//
int execve(const char *filename, char * const argv[], char * const envp[]) {
LOGI("preload hook execve filename: %s", filename);
int (*EXECVE_FUNC)(const char *filename, char * const argv[],
char * const envp[]) = NULL;
void *handle;
char *error;
int ret;
//打开动态链接库
handle = dlopen("/system/lib/libc.so", RTLD_LAZY);
if (!handle) {
LOGI("can not dlopen /system/lib/libc.so");
fprintf(stderr, "%s\n", dlerror());
}
//清除之前存在的错误
dlerror();
//获取一个函数
EXECVE_FUNC = dlsym(handle, "execve");
if ((error = dlerror()) != NULL) {
LOGI("can not dlsym execve");
fprintf(stderr, "%s\n", error);
}
char * const envs[] = { "LD_PRELOAD=/data/local/tmp/libmyfopen.so", NULL };
//用原来的参数运行
ret = (*EXECVE_FUNC)(filename, argv, envs);
//关闭动态链接库
dlclose(handle);
return ret;
}
实际操作:
把exec run run1 libmyfopen.so push进/data/local/tmp/
root@g2:/data/local/tmp # ./exec /data/local/tmp/libmyfopen.c
输出:
tag: huacai_uncle
LD_PRELOAD=/data/local/tmp/libmyfopen.so
preload hook fopen path: /data/local/tmp/run mode: r
run /data/local/tmp/libmyfopen.so
preload hook execve filename: ./run1
preload hook fopen path: /data/local/tmp/run1 mode: r
run1 done.
先给咱小白兄弟们引下路,篇幅问题想了解更多关于PRELOAD hook麻烦移步到google。loader加载会把LD_PRELOAD 指向so中的符号覆盖相同符号名的符号,用自己的函数替换系统库的函数,实现PRELOAD hook。
本次分享由4个c文件组成。exec 负责启动第一个bin 并指定LD_PRELOAD 参数为libmyfopen.so 这个so 中实现了两个函数,fopen() 与execve()。这两个函数定义与libc的fopen() 与execve()函数一样。所以系统再加载libc.so 时导出符号表fope()n与execve()就被libmyfopen.so这两个函数占了。run只负责启动run1。因为run的evecve()已经被hook,run调用execve()启动run1时,run1的fopen() 与execve()也被hook了。这些变化能从log输出看出来。
以下代码:
首先是exec.c //负责启动run 这个bin,并把自己的so 指定为LD_PRELOAD 参数。
#include <stdio.h>
#include <unistd.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv) {
char preload_lib[50];
sprintf(preload_lib, "LD_PRELOAD=%s", argv[1]);
LOGI("LD_PRELOAD=%s",argv[1]);
char * const args[] = { "./run", NULL };
char * const envs[] = { preload_lib, NULL };
execve("./run", args, envs);
LOGI("ex done.");
return 0;
}
然后是run.c //第一个bin 这个bin启动第二个bin
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include<unistd.h>
#include<sys/types.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv)
{
FILE * handler = fopen("/data/local/tmp/run","r");
if(handler != NULL){
LOGI("run %s\n",getenv("LD_PRELOAD"));
}
char *const args[] = {"./run1",NULL};
execve("./run1",args,NULL);
LOGI("run done.");
return 0;
}
最后是run1.c 这个bin
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include<unistd.h>
#include<sys/types.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int main(int argc, char **argv)
{
FILE * handler = fopen("/data/local/tmp/run1","r");
printf("run1 done.");
LOGI("run1 done.");
return 0;
}
再看一下preload so. myfopen.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <jni.h>
#include <android/log.h>
#define TAG "huacai_uncle"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
FILE * fopen(const char * path, const char * mode) {
if (path == NULL || strlen(path) == 0) {
LOGI("preload hook fopen path is NULL");
return NULL ;
}
LOGI("preload hook fopen path: %s mode: %s", path, mode);
FILE * (*FOPEN_FUNC)(const char * path, const char * mode) = NULL;
void *handle;
char *error;
FILE *ret;
//打开动态链接库
handle = dlopen(LIB_PATH, RTLD_LAZY);
if (!handle) {
LOGI("can not dlopen /system/lib/libc.so");
fprintf(stderr, "%s\n", dlerror());
}
//清除之前存在的错误
dlerror();
//获取一个函数
FOPEN_FUNC = dlsym(handle, "fopen");
if ((error = dlerror()) != NULL) {
LOGI("can not dlsym fopen");
fprintf(stderr, "%s\n", error);
}
//用原来的参数运行
ret = (*FOPEN_FUNC)(path, mode);
//关闭动态链接库
dlclose(handle);
return ret;
}
//---------------------hook exec----------------------//
int execve(const char *filename, char * const argv[], char * const envp[]) {
LOGI("preload hook execve filename: %s", filename);
int (*EXECVE_FUNC)(const char *filename, char * const argv[],
char * const envp[]) = NULL;
void *handle;
char *error;
int ret;
//打开动态链接库
handle = dlopen("/system/lib/libc.so", RTLD_LAZY);
if (!handle) {
LOGI("can not dlopen /system/lib/libc.so");
fprintf(stderr, "%s\n", dlerror());
}
//清除之前存在的错误
dlerror();
//获取一个函数
EXECVE_FUNC = dlsym(handle, "execve");
if ((error = dlerror()) != NULL) {
LOGI("can not dlsym execve");
fprintf(stderr, "%s\n", error);
}
char * const envs[] = { "LD_PRELOAD=/data/local/tmp/libmyfopen.so", NULL };
//用原来的参数运行
ret = (*EXECVE_FUNC)(filename, argv, envs);
//关闭动态链接库
dlclose(handle);
return ret;
}
实际操作:
把exec run run1 libmyfopen.so push进/data/local/tmp/
root@g2:/data/local/tmp # ./exec /data/local/tmp/libmyfopen.c
输出:
tag: huacai_uncle
LD_PRELOAD=/data/local/tmp/libmyfopen.so
preload hook fopen path: /data/local/tmp/run mode: r
run /data/local/tmp/libmyfopen.so
preload hook execve filename: ./run1
preload hook fopen path: /data/local/tmp/run1 mode: r
run1 done.
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
谁下载
看原图
赞赏
雪币:
留言: