Git Product home page Git Product logo

research-rootkit's Introduction

English 中文

LibZeroEvil & the Research Rootkit project

This is LibZeroEvil & the Research Rootkit project, in which there are step-by-step, experiment-based courses that help to get you started and keep your hands dirty with offensive or defensive development in the Linux kernel, and also guide you with demonstrative examples through the underlying core library, LibZeroEvil, which attempts to be a real-world consumable programming framework for any evil or good kernel-land invaders or defenders.

That being said, it's just the beginning and LibZeroEvil is still in its infancy, serving educational purposes mainly.

Warning

It's never recommended to perform kernel module experiments on a physical machine, unless the owner will never complain about frequent rebooting or forced halting and possible data or work loss.

You have been warned.

Guidelines on Creating New Issues or Contributing

If a course doesn't compile, or compiles but doesn't work as expected, e.g. crashing or hanging your system, feel free to create a new issue. But before that, consider the following.

  1. Search existing issues to ensure that it won't be duplicated.
  2. Attach detailed information of your system, e.g., uname --all, and what your compiler throws on you, i.e., the error information, so that others can successfully reproduce your issue and manage to help you out.

    If you can't figure out which error is the most significant one, paste all of them verbatim inside Markdown triple quotes.

  3. Remember that kernel compatibility issues are the most common ones, since the author paid virtually no attention to that. However, it's my pleasure to learn about and fix them.
  4. Some courses are x64 only for the time being.

Information on Kernel Compatibility

Tested Kernel

My major development environment.

  • Kali

    Linux anon 4.6.0-kali1-amd64 #1 SMP Debian 4.6.3-1kali1 (2016-07-12) x86_64 GNU/Linux.

Compilable Kernel

That is, ./tests/makeall.sh --quiet reports no error, but I haven't tested the functionality.

  • Arch

    Linux anon 4.6.4-1-ARCH #1 SMP PREEMPT Mon Jul 11 19:12:32 CEST 2016 x86_64 GNU/Linux.

  • Ubuntu 14.04

    Linux anon 4.2.0-42-generic #49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Known Unresolved Compatibility Issues

  • struct dir_context doesn't exist on kernel version 3.10 and earlier.

    For example, CentOS 7, Linux localhost.localdomain 3.10.0-327.22.2.el7.x86_64 #1 SMP Thu Jun 23 17:05:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux.

Notice on Directory Structure

The directory structure of this repository might change drastically without any notifications.

Available Courses

More courses might be designed and added here later.

Course 1: Modifying / Hooking the sys_call_table

  • Experiment 1: hello

    Hello World! kernel module.

  • Experiment 2: sys_call_table

    Get sys_call_table 's address by brute-force memory searching starting from PAGE_OFFSET.

  • Experiment 3: write_protection

    Disable or enable Write Protection via the CR0 register.

  • Roundup Experiment 1: fsmon

    A primitive file monitor based on system call hooking.

    Hooked functions: open, unlink, unlinkat.

  • Roundup Experiment 2: psmon

    A primitive process monitor via system call hooking.

    Hooked functions: execve.

    • Notice

      I have seen reports that the method used in this experiment would not work normally due to inconsistent ABI of stub_execve, which requires further investigation.

  • Roundup Experiment 3: fshid

    A primitive file-hiding demonstration using system call hooking.

    Hooked functions: getdents, getdents64.

    Hidden files: 032416_525.mp4.

Course 2: Implementing fundamental functionalities of rootkits

  • Experiment 1: root

    Providing a root backdoor.

  • Experiment 2: komon

    Preventing modules from initializing and functioning by substituting their init and exit functions when MODULE_STATE_COMING is notified to module notifiers.

  • Experiment 3: fshid

    Hiding files by hooking filldir.

  • Experiment 4: pshid

    Hiding processes by hiding entries under /proc.

  • Experiment 5: pthid

    Hiding ports by filtering contents in /proc/net/tcp and the like by hooking the show function of their seq_file interfaces.

  • Experiment 6: kohid

    Hiding modules by hiding entries in /sys/module and filtering contents of /proc/modules by hooking its show function.

    This experiment combines the techniques demonstrated in Experiment 4: pshid and Experiment 5: pthid.

Course 3: Infecting critical kernel modules for persistence and more

  • Experiment 1: elf

    Providing elementary materials on ELF parsing and modifying.

    This experiment implemented an essential tool, i.e. setsym, for following experiments, and also two trivial tools, lssec resembling readelf -S and lssym resembling readelf -s / objdump -t.

    They are coded for 64-bit ELF only, but it shouldn't be difficult to adapt.

  • Experiment 2: noinj

    Hijacking / Hooking the init and exit function of the module with functions in the same module by modifying the symbol table.

  • Experiment 3: codeinj

    Injecting the adapted fshid (See Experiment 3 of Course 2) into a demonstrative simple module (i.e. without static __init or static __exit), and hooking / hijacking its init and exit functions by modifying the symbol table.

  • Roundup Experiment: real

    Injecting the adapted fshid (See Experiment 3 of Course 2) into a real-world kernel module (i.e. with static __init or static __exit) by linking, and hooking / hijacking its init and exit functions by modifying the symbol table.

Course 4: Modifying / Patching the entry_SYSCALL_64

This is x64 only. However, it's not difficult to adapt.

  • Experiment 1: get

    Getting the sys_call_table 's address in the machine code of entry_SYSCALL_64 by searching the identifying bytes ff 14 c5.

  • Experiment 2: set

    Patching the sys_call_table 's address in the machine code of entry_SYSCALL_64 with a faked but innocuous, i.e. unmodified, one.

  • Experiment 3: rec

    Recovering the sys_call_table 's address in the machine code of entry_SYSCALL_64 to that obtained via sys_close -based memory searching.

  • Roundup Experiment: ifmon

    Monitoring network flow (especially GET & POST) by hooking sys_sendto using the method demonstrated in the above three experiments on entry_SYSCALL_64.

Course 5: Inline Hooking

  • Experiment 1: jmp

    Patching the starting bytes of target functions with control flow redirection instructions, e.g. PUSH RET, JMP or INT, which transfer control to our function, where our tasks are performed, including restoring those bytes and invoking the victim function if necessary.

Projects Of Interests

References & Further Readings

research-rootkit's People

Contributors

novicelive 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

research-rootkit's Issues

root.c ---error in ubuntukylin-14.04.1

Hello,NoviceLive

When I compile root.c in ubuntukylin-14.04.1,I got two errors.
Could you help me to solve it.
Thank you!

host: ubuntukylin-14.04.1-desktop-i386

ub@ubuntu:~/Desktop/research-rootkit-master/2-fundamentals/root$ make
make modules \
        --directory "/lib/modules/3.13.0-32-generic/build" \
        M="/home/ub/Desktop/research-rootkit-master/2-fundamentals/root"
make[1]: Entering directory `/usr/src/linux-headers-3.13.0-32-generic'
  CC [M]  /home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.o
In file included from include/linux/srcu.h:33:0,
                 from include/linux/notifier.h:15,
                 from include/linux/memory_hotplug.h:6,
                 from include/linux/mmzone.h:797,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:20:
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c: In function ‘write_handler’:
include/linux/cred.h:272:24: error: dereferencing pointer to incomplete type
  rcu_dereference((task)->real_cred)
                        ^
include/linux/rcupdate.h:521:11: note: in definition of macro ‘__rcu_dereference_check’
   typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
           ^
include/linux/rcupdate.h:709:28: note: in expansion of macro ‘rcu_dereference_check’
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^
include/linux/cred.h:272:2: note: in expansion of macro ‘rcu_dereference’
  rcu_dereference((task)->real_cred)
  ^
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:92:31: note: in expansion of macro ‘__task_cred’
         cred = (struct cred *)__task_cred(current);
                               ^
include/linux/cred.h:272:24: error: dereferencing pointer to incomplete type
  rcu_dereference((task)->real_cred)
                        ^
include/linux/rcupdate.h:521:38: note: in definition of macro ‘__rcu_dereference_check’
   typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
                                      ^
include/linux/rcupdate.h:709:28: note: in expansion of macro ‘rcu_dereference_check’
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^
include/linux/cred.h:272:2: note: in expansion of macro ‘rcu_dereference’
  rcu_dereference((task)->real_cred)
  ^
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:92:31: note: in expansion of macro ‘__task_cred’
         cred = (struct cred *)__task_cred(current);
                               ^
In file included from include/uapi/linux/stddef.h:1:0,
                 from include/linux/stddef.h:4,
                 from /usr/src/linux-headers-3.13.0-32-generic/include/uapi/linux/posix_types.h:4,
                 from include/uapi/linux/types.h:13,
                 from include/linux/types.h:5,
                 from include/linux/list.h:4,
                 from include/linux/module.h:9,
                 from /home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:20:
include/linux/cred.h:272:24: error: dereferencing pointer to incomplete type
  rcu_dereference((task)->real_cred)
                        ^
include/linux/compiler.h:352:43: note: in definition of macro ‘ACCESS_ONCE’
 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
                                           ^
include/linux/rcupdate.h:613:2: note: in expansion of macro ‘__rcu_dereference_check’
  __rcu_dereference_check((p), rcu_read_lock_held() || (c), __rcu)
  ^
include/linux/rcupdate.h:709:28: note: in expansion of macro ‘rcu_dereference_check’
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^
include/linux/cred.h:272:2: note: in expansion of macro ‘rcu_dereference’
  rcu_dereference((task)->real_cred)
  ^
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:92:31: note: in expansion of macro ‘__task_cred’
         cred = (struct cred *)__task_cred(current);
                               ^
include/linux/cred.h:272:24: error: dereferencing pointer to incomplete type
  rcu_dereference((task)->real_cred)
                        ^
include/linux/compiler.h:352:50: note: in definition of macro ‘ACCESS_ONCE’
 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
                                                  ^
include/linux/rcupdate.h:613:2: note: in expansion of macro ‘__rcu_dereference_check’
  __rcu_dereference_check((p), rcu_read_lock_held() || (c), __rcu)
  ^
include/linux/rcupdate.h:709:28: note: in expansion of macro ‘rcu_dereference_check’
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^
include/linux/cred.h:272:2: note: in expansion of macro ‘rcu_dereference’
  rcu_dereference((task)->real_cred)
  ^
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:92:31: note: in expansion of macro ‘__task_cred’
         cred = (struct cred *)__task_cred(current);
                               ^
In file included from include/linux/srcu.h:33:0,
                 from include/linux/notifier.h:15,
                 from include/linux/memory_hotplug.h:6,
                 from include/linux/mmzone.h:797,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:20:
include/linux/cred.h:272:24: error: dereferencing pointer to incomplete type
  rcu_dereference((task)->real_cred)
                        ^
include/linux/rcupdate.h:526:13: note: in definition of macro ‘__rcu_dereference_check’
   ((typeof(*p) __force __kernel *)(_________p1)); \
             ^
include/linux/rcupdate.h:709:28: note: in expansion of macro ‘rcu_dereference_check’
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^
include/linux/cred.h:272:2: note: in expansion of macro ‘rcu_dereference’
  rcu_dereference((task)->real_cred)
  ^
/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.c:92:31: note: in expansion of macro ‘__task_cred’
         cred = (struct cred *)__task_cred(current);
                               ^
make[2]: *** [/home/ub/Desktop/research-rootkit-master/2-fundamentals/root/root.o] Error 1
make[1]: *** [_module_/home/ub/Desktop/research-rootkit-master/2-fundamentals/root] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.13.0-32-generic'
make: *** [default] Error 2
ub@ubuntu:~/Desktop/research-rootkit-master/2-fundamentals/root$ 
  • Edit by NoviceLive: Quoted error information as in Markdown.

Articles in freebuf are inaccessible

Articles in freebuf are inaccessible, could you please release the articles in another place,? Thanks.

Server error
An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.

readme.md grammar mistake

Guidelines on Creating New Issues or Contributing

If a course doesn't compile, or do compile but doesn't work as expected

change to:
If a course doesn't compile, or does compile but... or
If a course doesn't compile, or compiles but...

Don't use do for he/she/it

2-fundamentals无法实现隐藏的效果

你好,这个仓库真的很酷,帮助了我很多!!

当我在测试2-fundamentals中的文件隐藏pshid时(fshid也有相同错误),我在make以后第一次插入模块,会提示有未定义的符号:
image
然后在dmesg窗口显示:
image

我明白这是real_iterate为空时程序直接退出。当我第二次插入模块时,没有错误发生:
image
dmesg信息如下:
image
很显然,此时real_iterate不为空,而是使用之前fake_iterate的值。

当我认为一切可以工作时,却发生了意外,内核模块无法按照既定的方式工作,即:无法隐藏进程或者文件

当我尝试多次插入和删除模块时,发现一个非常有意思的现象:
image

real_iterate和old_iterate的值只在两个值之间固定的变化,我不知道这是不是出现该错误的原因,所以该实验结果图片提供给您参考。

我在Ubuntu 16 的虚拟机环境上进行的测试,uname -a的输出为:
Linux hq-virtual-machine 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

最后,期待您的回复!

fsmon hang in kernel 3.10.0

➜  ~ git clone https://github.com/NoviceLive/research-rootkit.git
Cloning into 'research-rootkit'...
remote: Counting objects: 247, done.
remote: Total 247 (delta 0), reused 0 (delta 0), pack-reused 247
Receiving objects: 100% (247/247), 48.99 KiB | 48.00 KiB/s, done.
Resolving deltas: 100% (131/131), done.
➜  ~ cd research-rootkit/1-sys_call_table/fsmon
➜  fsmon git:(master) ls
Makefile  fsmon.c  lib
➜  fsmon git:(master) make
make modules \
    --directory "/lib/modules/3.10.0-327.22.2.el7.x86_64/build" \
    M="/root/research-rootkit/1-sys_call_table/fsmon"
make[1]: Entering directory `/usr/src/kernels/3.10.0-327.22.2.el7.x86_64'
  CC [M]  /root/research-rootkit/1-sys_call_table/fsmon/fsmon.o
  CC [M]  /root/research-rootkit/1-sys_call_table/fsmon/lib/lib.o
  LD [M]  /root/research-rootkit/1-sys_call_table/fsmon/fsmonko.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /root/research-rootkit/1-sys_call_table/fsmon/fsmonko.mod.o
  LD [M]  /root/research-rootkit/1-sys_call_table/fsmon/fsmonko.ko
make[1]: Leaving directory `/usr/src/kernels/3.10.0-327.22.2.el7.x86_64'
➜  fsmon git:(master) insmod fsmonko.ko

execve hook causes segmentation faults in some cases

On 64-bit (amd64/x86_64) Redhat / CentOS 6.x (kernel 2.6.32), vanilla, I have experienced an issue with the execve stub. While indeed we can hook stub_execve, record the arguments e.g. the program being called, the environment, the cli arguments, etc. and programs will run fine there are others that outright crash. The stack apparently gets damaged in some way and I suppose it has something to do with the way that we hook it, do our own things on the stack with our hook function, and then return to stub_exec. Something certainly is not working as expected.

This is evident when the 'psmonko.ko' module is loaded.

Programs that I have found to fail are the linker during the linking phase of compilation as well as gdb.

To replicate this, load psmonko.ko (in 1-sys_call_table/psmon) and run a few regular programs and see the module's output in /var/log/messgaes; everything is well and good. However, then run 'gdb' or a 'make'; or run gcc with linking an application as the goal, such as gcc -o test test.c. You will get segmentation faults. I have the core dump and then proceed to unload the module, load the core dump on the binary, and see statements/warnings about there being stack issues.

Any idea how to get around this? Do we need to do something to the stack in our execve stugb hook prior to jumping to to the original?

Thanks

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.