-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathdetect_preload.c
112 lines (89 loc) · 3.45 KB
/
detect_preload.c
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// This program will attempt to use libdl's functions to locate any possible modifications to libc functions via LD_PRELOAD attacks.
// If your malware can hide from all of these detection methods, then you officially have a secure piece of userland malware.
// You can add more symbols to check below. You don't really need that many.
// Hooking dlsym will stop dladdr_check from returning anything other than 0. You can also hook dladdr, and just make it segfault in certain conditions.
// Hiding from dlsym is strange. But it can be done. I promise. :p
// Hooking dlinfo is easier than hooking dlsym in my opinion. Hooking dlinfo will stop dlinfo_check from
// revealing your malware.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <link.h>
#include <dlfcn.h>
// add your own libc symbols to check if you wish
static const char *symbols[] = {
"rename", "renameat",
"stat", "stat64",
"fstat", "fstat64",
"lstat", "lstat64",
"__lxstat", "__lxstat64",
"__fxstat", "__fxstat64",
"__xstat", "__xstat64",
NULL
};
int dladdr_check(void)
{
void *dls_handle;
const char *symbol;
int i = 0, hooked_funcs = 0;
if(!(dls_handle = dlopen("libc.so.6", RTLD_LAZY))) exit(EXIT_FAILURE);
#ifdef VERBOSE
printf("[+] beginning dlsym/dladdr check.\n");
#endif
while((symbol = symbols[i++]))
{
#ifdef VERBOSE
printf("[+] checking \033[1;32m%s\033[0m.\n", symbol);
#endif
void *real_symbol_addr, *curr_symbol_addr;
real_symbol_addr = dlsym(dls_handle, symbol);
curr_symbol_addr = dlsym(RTLD_NEXT, symbol);
if(real_symbol_addr != curr_symbol_addr)
{
Dl_info real_nfo, curr_nfo;
dladdr(real_symbol_addr, &real_nfo);
dladdr(curr_symbol_addr, &curr_nfo);
#ifdef VERBOSE
printf("[-] function %s possibly \033[1;31mhijacked\033[0m / location of shared object file: %s\n", symbol, curr_nfo.dli_fname);
#endif
hooked_funcs++;
}
}
dlclose(dls_handle);
#ifdef VERBOSE
printf("\n[+] dlsym/dladdr check finished.\n");
#endif
return hooked_funcs;
}
void dlinfo_check(void)
{
struct link_map *lm;
dlinfo(dlopen(NULL, RTLD_LAZY), 2, &lm);
#ifdef VERBOSE
printf("[+] beginning dlinfo check.\n");
#endif
while(lm != NULL)
{
if(strlen(lm->l_name) > 0) printf("%p %s\n", (void *)lm->l_addr, lm->l_name);
lm = lm->l_next;
}
#ifdef VERBOSE
printf("[+] dlinfo check finished.\n");
#endif
}
int main(void)
{
if(getenv("LD_PRELOAD")) printf("OK.. LD_PRELOAD is visible in the local environment variables.. little warning\n");
if(access("/etc/ld.so.preload", F_OK) != -1) printf("OK.. /etc/ld.so.preload DOES definitely exist.. little warning\n");
printf("[+] finished basic checks\n\n");
dlinfo_check(); printf("\n");
int hooked_funcs = dladdr_check();
if(hooked_funcs > 0) printf("[!] the dladdr check revealed that there are %d possibly hooked functions. YOUR MALWARE SUUUUCKS.\n", hooked_funcs);
if(hooked_funcs == 0) printf("[+] no modifications to any libc functions were found. no LD_PRELOAD malware loaded, or your malware is decent.\n");
return 0;
}