DEV Community

rvbbit
rvbbit

Posted on

RVBBIT: What I Learned Building a Linux Kernel Rootkit PoC — and Why I Ended Up Studying Detection

I didn't start RVBBIT with the idea of building a security framework.

It was much simpler than that.

I wanted to understand Linux rootkits beyond reading about them.

I had been studying techniques such as syscall hooking, DKOM, process hiding and kernel module hiding separately, and at some point I realized that reading another explanation wasn't going to answer the questions I had.

I wanted to see what happened when these techniques actually lived together.

So I started writing RVBBIT.

The first version was an educational Linux kernel rootkit PoC. The techniques themselves were not new, and I don't want to pretend otherwise. Most of them have been documented and discussed for years.

What made the project interesting to me was putting several of them into one implementation and watching where they interacted, where they broke, and what they failed to hide.

That last part eventually changed the direction of the project completely.

Project RVBBIT:
https://github.com/buter-chkalova/project-rvbbit


It started with hiding things

The original goal was fairly straightforward: take several established Linux rootkit techniques and understand them by implementing them.

RVBBIT ended up covering experiments around:

  • process hiding and DKOM;
  • kernel module hiding;
  • syscall interception;
  • filesystem visibility;
  • TCP connection visibility;
  • selected interference with eBPF-related mechanisms;
  • persistence.

At first, I was looking at each feature mostly from the offensive side.

Can a process disappear from a normal enumeration path?

Can a loaded module disappear from the view an administrator normally expects?

Can directory entries be filtered before userspace sees them?

Can the representation of a TCP connection be changed without removing the connection itself?

Those are useful implementation questions, but after working on the project for a while I noticed that they all had something in common.

I wasn't really removing things.

I was changing how they were observed.

That sounds obvious when written down. It wasn't as obvious to me when I started.


A hidden process is still a process

Take process hiding.

A running process has kernel state associated with it. Userspace tools don't somehow inspect the physical reality of the machine and discover processes independently. They ask the operating system for information.

Normally we can think about it roughly like this:

kernel state
     |
     v
kernel interface
     |
     v
userspace
Enter fullscreen mode Exit fullscreen mode

If code inside the kernel interferes with that path, the result changes:

actual state
     |
     v
modified observation path
     |
     v
reported state
Enter fullscreen mode Exit fullscreen mode

The process may still be executing.

The interesting part is that one observer no longer reports it.

This distinction started appearing everywhere in RVBBIT.

With DKOM-style manipulation, the object can continue to exist while a relationship used to enumerate it has changed.

With file hiding, the file doesn't necessarily stop existing. A directory listing can simply stop reporting its entry.

With network hiding, the connection can remain active while one representation of network state no longer shows it.

So I gradually stopped thinking in terms of:

"How do I hide X?"

and started thinking:

"Which view of X am I actually changing?"

That turned out to be a much better question.


The techniques aren't new. Combining them was the useful part.

This is something I want to be explicit about.

RVBBIT does not contain some previously unknown Linux rootkit primitive.

DKOM isn't new.

Syscall interception isn't new.

Module hiding isn't new.

Neither is filtering filesystem or network information.

But studying these things separately can make them look cleaner than they really are.

Once several mechanisms exist inside the same project, you start running into relationships between them.

A concealment mechanism may affect one observation path and leave another untouched.

A persistence mechanism creates artifacts outside the kernel.

A method that works on one kernel version may depend on assumptions that disappear on another.

Two security tools may look independent while actually receiving information through the same kernel mechanism.

Those interactions became more interesting to me than adding another hiding feature.

Interestingly, this was also one of the things other researchers noticed about RVBBIT.

In April 2026, the Spanish cybersecurity publication Hackplayers published a technical analysis of the project:

RVBBIT: anatomía de un rootkit LKM moderno basado en stealth, DKOM y anti-eBPF

https://www.hackplayers.com/2026/04/rvbbit-anatomia-de-un-rootkit-lkm.html

They went through several parts of the implementation, including DKOM, syscall interception, hiding mechanisms and the project's interaction with eBPF-related observability.

What I appreciated about their analysis was that they didn't present RVBBIT as a completely new rootkit technique. They looked at it as a case study that brought a number of existing ideas together.

That's much closer to how I see the project myself.

Later, the project also appeared in a Chinese technical article on CSDN:

内核里的“幽灵”:一套Linux Rootkit隐身术完全拆解

https://blog.csdn.net/chen1415886044/article/details/161462914

Seeing other people independently take the code apart was probably more useful than getting another GitHub star. It showed me which parts of the project were understandable from the outside and which ideas attracted attention without me explaining them first.


Syscall hooking gave me a different kind of question

Syscall interception is a good example of how my thinking changed.

From the offensive side, the idea is familiar.

Very roughly:

userspace
    |
    v
system call
    |
    v
sys_call_table
    |
    v
kernel handler
Enter fullscreen mode Exit fullscreen mode

Change the relevant mapping and you can redirect execution.

When I first worked with this, I was interested mainly in the interception itself.

Later I realized the defensive question was almost sitting next to it:

If I expect a syscall entry to point somewhere, and it suddenly points somewhere else, can I verify that?

That sounds like a small change in perspective, but it changes the problem.

Instead of trying to recognize every possible behavior produced by a hook, you can start asking questions about integrity.

What was the expected target?

What is the current target?

Where does my expected value come from?

And, more importantly: why should I trust that source?

The last question is where things become difficult.

A detector inside a compromised kernel is still inside a compromised kernel.


/proc taught me not to confuse tools with independent observers

Another thing that became obvious while working on visibility was that running two different commands does not necessarily give you two independent observations.

Imagine two tools receiving their information through the same modified kernel path:

             kernel state
                  |
             modified path
                  |
          +-------+-------+
          |               |
        tool A           tool B
Enter fullscreen mode Exit fullscreen mode

Both tools agree.

And both can still be wrong.

This matters when thinking about rootkit detection because "I'll compare what two tools report" only helps if those tools ultimately depend on sufficiently independent sources.

If both trust the same compromised representation, agreement doesn't tell us much.

This became one of the ideas I wanted to explore further.


eBPF made the observability problem even more interesting

I also became interested in eBPF because modern Linux security tooling doesn't have to rely entirely on periodic enumeration.

It can observe events much closer to where they occur.

That changes the problem for a traditional rootkit.

RVBBIT contains experiments involving selected BPF-related operations, but I don't consider this some universal "anti-eBPF" mechanism. Real eBPF-based security systems are considerably more complicated than that.

The useful lesson was different.

Imagine a security system stops receiving the telemetry it expects.

Does that mean nothing happened?

Or does it mean something interfered with the observer?

Those two states look similar from the perspective of an empty event stream, but from a security perspective they are completely different.

At that point I started thinking about the observer itself as something whose integrity matters.

That idea later carried over into RVBBIT Arsenal.


At some point I stopped wanting more rootkit features

There was a point where I could have continued adding things to RVBBIT.

Another hiding mechanism. Another hook. Another persistence experiment.

But I wasn't sure that would make the project more useful.

The question I kept coming back to was:

If I know exactly how I hid something, where should I look for the evidence I failed to remove?

That became the reason for starting the second project.

RVBBIT Arsenal:
https://github.com/buter-chkalova/rvbbit-arsenal

Arsenal separates the work into offensive and defensive sides:

I initially thought about this as "attack versus defense."

I don't anymore.

The model I find more useful now is:

technique
   |
   v
state modification
   |
   v
visibility change
   |
   v
something remains observable
   |
   v
detection idea
   |
   v
limitations
Enter fullscreen mode Exit fullscreen mode

The last step matters just as much as the others.


RvbbitSafe isn't an "anti-rootkit"

The defensive part of Arsenal is called RvbbitSafe.

An earlier version of the project used much stronger language around the defensive side. Looking back, I don't think that was technically justified.

RvbbitSafe isn't a universal Linux anti-rootkit, and I don't present it as one now.

It's a research prototype built around a simpler idea:

if one representation of system state has been manipulated, can another representation expose the difference?

Process visibility is a good example.

Imagine two ways of reasoning about whether the same process exists:

              process
                 |
        +--------+--------+
        |                 |
        v                 v
     view A             view B
        |                 |
        +--------+--------+
                 |
              compare
Enter fullscreen mode Exit fullscreen mode

Normally, we expect the views to agree.

If I deliberately alter the state used by one of them and the other remains intact, the disagreement can become a detection signal.

This is generally described as a cross-view approach.

But while implementing it, another problem becomes obvious.

How independent are those views really?

If an attacker modifies both of them, the detector can lose the discrepancy.

If they share some lower-level dependency that has already been corrupted, they may agree for the wrong reason.

So the interesting part isn't just:

"I have two views."

It's:

"What does each view trust?"


This became the main question for me

A simplified security stack might look like this:

security application
        |
        v
userspace interface
        |
        v
kernel interface
        |
        v
kernel structures
        |
        v
hardware
Enter fullscreen mode Exit fullscreen mode

Every observer sits somewhere in that stack.

And every observer has a trust boundary.

If the attacker operates below it, the information above that boundary may no longer describe reality accurately.

That sounds theoretical, but RVBBIT gave me concrete examples of it.

A userspace process monitor can trust /proc.

Then kernel code changes what /proc reports.

A kernel detector can avoid that userspace problem.

But now the question becomes which kernel structures the detector trusts.

Move the observer down a layer and you don't eliminate trust. You move the trust boundary.

That is probably the biggest thing I learned from these projects.

Not how to unlink something from a list.

Not how to intercept a syscall.

Those are useful technical exercises, but the more general lesson was:

Detection is only as trustworthy as the assumptions behind the observer.


Where the two projects stand now

I think of the projects differently today.

Project RVBBIT is the original offensive research PoC.

It collects several established Linux kernel manipulation and concealment techniques in one place and provides a relatively compact environment for studying how they interact.

RVBBIT Arsenal is the continuation of that work.

Instead of asking only how visibility can be manipulated, it tries to reason about what remains visible afterward.

The relationship is roughly:

RVBBIT
   |
   |  How can I manipulate this view?
   v
RVBBIT Arsenal
   |
   |  What survives the manipulation?
   v
Detection research
Enter fullscreen mode Exit fullscreen mode

Neither project is meant to represent production malware.

RVBBIT doesn't claim reliable evasion against modern EDR products.

It doesn't claim that the techniques are novel.

RvbbitSafe doesn't claim generic rootkit detection.

I think those limitations make the projects more useful, not less.

They make it possible to discuss what the code actually demonstrates instead of what an idealized rootkit or detector could theoretically do.


If I started RVBBIT again

I'd do one thing very differently.

I would document the defensive side while writing the offensive code.

For every mechanism, I'd keep notes around five questions:

  1. What exactly am I changing?
  2. Which observer stops seeing it?
  3. Which state remains untouched?
  4. Who could observe that remaining state?
  5. How could that observation fail?

That would have saved me a lot of time later.

It also would have made the progression from RVBBIT to Arsenal much more obvious from the beginning.

But I probably wouldn't have understood why those questions mattered without first building the offensive side.

So maybe doing it backwards was useful after all.


What's next

I don't currently think RVBBIT needs a huge list of additional concealment features.

There are already enough mechanisms there to ask interesting questions.

I'm more interested in going deeper into:

  • Linux kernel observability;
  • cross-view detection;
  • kernel integrity;
  • eBPF-based telemetry;
  • sensor integrity;
  • trust boundaries;
  • the difference between an object's state and its representation.

In other words, I'm still interested in offensive kernel techniques.

I'm just increasingly interested in what they teach us about defense.

RVBBIT started with a fairly simple question:

How can kernel code change what userspace sees?

The question I'm left with is better:

If I can't trust what I'm seeing, where can I get another view?

I don't think there is one universal answer.

That's exactly why I want to keep working on it.


Projects

Project RVBBIT — Linux Kernel Rootkit Research PoC
https://github.com/buter-chkalova/project-rvbbit

RVBBIT Arsenal — Offensive & Defensive Linux Kernel Security Research
https://github.com/buter-chkalova/rvbbit-arsenal

Independent technical coverage

Hackplayers (Spain)
RVBBIT: anatomía de un rootkit LKM moderno basado en stealth, DKOM y anti-eBPF
https://www.hackplayers.com/2026/04/rvbbit-anatomia-de-un-rootkit-lkm.html

CSDN (China)
内核里的“幽灵”:一套Linux Rootkit隐身术完全拆解
https://blog.csdn.net/chen1415886044/article/details/161462914


RVBBIT and RVBBIT Arsenal are research projects intended for cybersecurity education, controlled laboratory experimentation, malware analysis, and defensive security research. Kernel-level experiments should only be performed on systems you own or where you have explicit authorization.

Top comments (0)