License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

About Elkeid(AgentSmith-HIDS) Driver

Elkeid Driver 主要是为信息安全需求而设计的。

Elkeid Driver 主要通过 Kprobe Hook Kernel Function 来提供丰富而准确的数据收集功能,包括内核级进程执行探测,特权升级监控,网络审计等等。 并且支持 Linux Namespace,因此对容器监控有着很好的实现。与传统的 User Space HIDS 相比,Elkeid 由于驱动的存在提供了更全面的信息,并提高了性能。

凭借其出色的数据收集能力,Elkeid Driver 还可以支持沙盒,蜜罐和审计等需求。

如果发现 Bug 欢迎提 Issue 或 加入飞书公开群参与讨论。

快速尝试

首先需要安装 Linux Headers,Linux Headers 的版本必须等于 uname -r

# clone and build
git clone https://github.com/bytedance/Elkeid.git
cd Elkeid/driver/LKM/
make clean && make
< CentOS only: run build script instead >
sh ./centos_build_ko.sh

# load and test (should run as root)
insmod hids_driver.ko
dmesg | tail -n 20
test/rst -q
< "CTRL + C" to quit >

# unload
rmmod hids_driver

我们提供部分预编译好的 Ko 文件

我们提供了一些预编译好的 Elkeid 内核模块,这些 Ko 文件包括了 Debian / CentOS / Ubuntu 等发行版的不同内核版本。

获取方式

如果所有链接都获取失败,则说明 预编译的 Ko 中,不包含当前系统的内核版本所需的 Ko 文件,需要自行编译。

wget "http://lf26-elkeid.bytetos.com/obj/elkeid-download/ko/hids_driver_1.7.0.10_$(uname -r)_amd64.ko"

内核模块的测试方法

可以通过 LTP 或者 KASAN 这两个方法对内核模块进行测试.

这里提供 LTP测试用例 文件

关于 Linux 发行版的兼容性

发行版版本号x64 架构内核内核后缀
Debian8,9,103.16~5.4.X-
Ubuntu14.04,16.04,18.04,20.043.12~5.4.Xgeneric
CentOS6.X,7.X,8.X2.6.32.0~5.4.Xel6,el7,el8
Amazon24.9.X~4.14.Xamzn2
AlibabaCloudLinux34.19.X~5.10.Xal7,al8
EulerOSV2.03.10.X-

关于 ARM64 (AArch64) 支持

  • 支持

关于 Linux Kernel Version 兼容性

  • Linux Kernel Version >= 2.6.32 && <= 6.3

关于容器兼容性

SourceNodename
Hosthostname
Dockercontainer name
K8spod name

Hook List

HookDataTypeNoteDefault
write1OFF
open2OFF
mprotect10only PROT_EXECOFF
nanosleep35OFF
connect42ON
accept43OFF
bind49ON
execve59ON
process exit60OFF
kill62OFF
rename82ON
link86ON
ptrace101only PTRACE_POKETEXT or PTRACE_POKEDATAON
setsid112ON
prctl157only PR_SET_NAMEON
mount165ON
tkill200OFF
exit_group231OFF
memfd_create356ON
dns query601ON
create_file602ON
load_module603ON
update_cred604only old uid ≠0 && new uid == 0ON
unlink605OFF
rmdir606OFF
call_usermodehelper_exec607ON
file_write608OFF
file_read609OFF
usb_device_event610ON
privilege_escalation611ON
port-scan detection612tunable via module param: psad_switchOFF

Anti Rootkit List

RootkitDataTypeDefault
interrupt table hook703ON
syscall table hook701ON
proc file hook700ON
hidden kernel module702ON

关于驱动数据传输

驱动数据协议

上述 Hook 点每命中一次,均会生成一条日志记录,记录之间使用 '\x17' 作为间隔符。

每条记录包含多个数据项,数据项之间使用 '\x1e' 作为间隔符。

一条记录数据通常由公共数据私有数据组合而成,而值得注意的是,Anti-rootkit 没有公共数据

公共数据

-------------------------------------------------------------------------------
|1        |2  |3  |4  |5   |6   |7   |8  |9   |10      |11       |12 |13      |
-------------------------------------------------------------------------------
|data_type|uid|exe|pid|ppid|pgid|tgid|sid|comm|nodename|sessionid|pns|root_pns|
-------------------------------------------------------------------------------

Write Data (1)

-----------
|14   |15 | 
-----------
|file||buf|
-----------

Open Data (2)

---------------------
|14   |15  |16      | 
---------------------
|flags|mode|filename|
---------------------

Mprotect Data (10)

-----------------------------------------------------
|14           |15       |16        |17     |18      |
-----------------------------------------------------
|mprotect_prot|owner_pid|owner_file|vm_file|pid_tree|
-----------------------------------------------------

Nanosleep Data (35)

----------
|14 |15  |
----------
|sec|nsec|
----------

Connect Data (42)

-----------------------------------
|14       |15 |16   |17 |18   |19 |
-----------------------------------
|sa_family|dip|dport|sip|sport|res|
-----------------------------------

Accept Data (43)

-----------------------------------
|14       |15 |16   |17 |18   |19 |
-----------------------------------
|sa_family|dip|dport|sip|sport|res|
-----------------------------------

Bind Data (49)

-------------------------
|14       |15 |16   |17 |
-------------------------
|sa_family|sip|sport|res|
-------------------------

Execve Data (59)

-----------------------------------------------------------------------------------------------------
|14  |15      |16   |17    |18 |19   |20 |21   |22       |23      |24 |25        |26 |27        |28 |
-----------------------------------------------------------------------------------------------------
|argv|run_path|stdin|stdout|dip|dport|sip|sport|sa_family|pid_tree|tty|socket_pid|ssh|ld_preload|res|
-----------------------------------------------------------------------------------------------------

Note:

  • socket_exe/dip/dport/sip/sport/sa_family 来自于进程所持的 fd 信息

  • ssh/ld_preload 来自于进程的环境变量信息

Process Exit Data (60)

该数据没有私有数据,仅有公共数据

Kill Data (62)

----------------
|14        |15 |
----------------
|target_pid|sig|
----------------

Rename Data (82)

-------------------------
|14      |15      |16   |
-------------------------
|old_name|new_name|sb_id|
-------------------------
-------------------------
|14      |15      |16   |
-------------------------
|old_name|new_name|sb_id|
-------------------------

Ptrace Data (101)

----------------------------------------------
|14            |15        |16  |17  |18      |
----------------------------------------------
|ptrace_request|target_pid|addr|data|pid_tree|
----------------------------------------------

Setsid Data (112)

该数据没有私有数据,仅有公共数据

Prctl Data (157)

_________________
|14    |15      | 
-----------------
|option|new_name|
-----------------

Mount Data (165)

_____________________________________
|14      |15 |16       |17    |18   | 
-------------------------------------
|pid_tree|dev|file_path|fstype|flags|
-------------------------------------

Tkill Data (200)

----------------
|14        |15 |
----------------
|target_pid|sig|
----------------

Exit Group Data (231)

该数据没有私有数据,仅有公共数据

Memfd Create Data (356)

______________
|14    |15   | 
--------------
|fdname|flags|
--------------

Dns Query Data (601)

--------------------------------------------------
|14   |15       |16 |17   |18 |19   |20    |21   |
--------------------------------------------------
|query|sa_family|dip|dport|sip|sport|opcode|rcode|
--------------------------------------------------

Create File data (602)

----------------------------------------------------------
|14 	  |15 |16   |17 |18   |19       |20        |21   |
----------------------------------------------------------
|file_path|dip|dport|sip|sport|sa_family|socket_pid|sb_id|
---------------------------------------------------------

Load Module Data (603)

---------------------------
|14      |15      |16     |
---------------------------
|ko_file|pid_tree|run_path|
---------------------------

Update Cred Data (604)

----------------------
|14      |15     |16 | 
----------------------
|pid_tree|old_uid|res|
----------------------
------
|14  |
------
|file|
------

Rmdir Data (606)

------
|14  |
------
|file|
------

call_usermodehelper_exec Data (607)

-------------------------
|1        |2  |3   |4   |
-------------------------
|data_type|exe|argv|wait|
-------------------------

File Write Data (608)

------------
|14  |15   |
------------
|file|sb_id|
------------
需要通过 Diver Filter 加入待观察列表,详情见 "关于 Driver Filter" 部分

File Read Data (609)

------------
|14  |15   |
------------
|file|sb_id|
------------
需要通过 Diver Filter 加入待观察列表,详情见 "关于 Driver Filter" 部分

USB Device Event Data (610)

-----------------------------------------
|14          |15          |16    |17    |
-----------------------------------------
|product_info|manufacturer|serial|action|
-----------------------------------------
action = 1 is USB_DEVICE_ADD
action = 2 is USB_DEVICE_REMOVE

Privilege Escalation (611)

------------------------------
|14   |15      |16    |17    |
------------------------------
|p_pid|pid_tree|p_cred|c_cred|
------------------------------
p_cred = uid|euid|suid|fsuid|gid|egid|sgid|fsgid
c_cred = uid|euid|suid|fsuid|gid|egid|sgid|fsgid

Port-scan attack detection (612)

------------------------------------------
|1   |2        |3  |4    |5  |6    |7    |
------------------------------------------
|type|sa_family|sip|sport|dip|dport|flags|
------------------------------------------

Proc File Hook (700)

-----------------------
|1        |2          |
-----------------------
|data_type|module_name|
-----------------------

Syscall Table Hook Data (701)

--------------------------------------
|1        |2          |3             |
--------------------------------------
|data_type|module_name|syscall_number|
--------------------------------------

Hidden Kernel Module Data (702)

-----------------------
|1        |2          |
-----------------------
|data_type|module_name|
-----------------------

Interrupt Table Hook Data (703)

----------------------------------------
|1        |2          |3               |
----------------------------------------
|data_type|module_name|interrupt_number|
----------------------------------------

关于 Driver Filter

Elkeid 驱动程序支持白名单以过滤出不需要的数据。我们提供两种类型的白名单,'exe' 白名单和 'argv' 白名单。 'exe' 白名单作用于 execve/create file/dns query/connect hook,而 'argv' 白名单仅作用于 execve hook。 出于性能和稳定性方面的考虑,'exe' 和 'argv' 白名单容量为 64。

白名单的字符串驱动位于: /dev/hids_driver_allowlist

OperationsFlagExample
ADD_EXECVE_EXE_SHITELISTY(89)echo Y/bin/ls > /dev/someone_allowlist
DEL_EXECVE_EXE_SHITELISTF(70)echo F/bin/ls > /dev/someone_allowlist
DEL_ALL_EXECVE_EXE_SHITELISTw(119)echo w/del_all > /dev/someone_allowlist
EXECVE_EXE_CHECKy(121)echo y/bin/ls > /dev/someone_allowlist && dmesg
ADD_EXECVE_ARGV_SHITELISTm(109)echo m/bin/ls -l > /dev/someone_allowlist
DEL_EXECVE_ARGV_SHITELISTJ(74)echo J/bin/ls -l > /dev/someone_allowlist
DEL_ALL_EXECVE_ARGV_SHITELISTu(117)echo u/del_all > /dev/someone_allowlist
EXECVE_ARGV_CHECKz(122)echo z/bin/ls -l > /dev/someone_allowlist && dmesg
PRINT_ALL_ALLOWLIST.(46)echo ./print_all > /dev/someone_allowlist && dmesg
ADD_WRITE_NOTIFIW(87)echo W/etc/passwd > /dev/someone_allowlist or echo W/etc/ssh/ > /dev/someone_allowlist support dir
DEL_WRITE_NOTIFIv(120)echo v/etc/passwd > /dev/someone_allowlist
ADD_READ_NOTIFIR(82)echo R/etc/passwd > /dev/someone_allowlist or echo R/etc/ssh/ > /dev/someone_allowlist support dir
DEL_READ_NOTIFIs(115)echo s/etc/passwd > /dev/someone_allowlist
DEL_ALL_NOTIFIA(65)echo A/del_all_file_notift > /dev/someone_allowlist

Filter define is:

#define ADD_EXECVE_EXE_SHITELIST 89         /* Y */
#define DEL_EXECVE_EXE_SHITELIST 70         /* F */
#define DEL_ALL_EXECVE_EXE_SHITELIST 119    /* w */
#define EXECVE_EXE_CHECK 121                /* y */
#define PRINT_ALL_ALLOWLIST 46              /* . */
#define ADD_EXECVE_ARGV_SHITELIST 109       /* m */
#define DEL_EXECVE_ARGV_SHITELIST 74        /* J */
#define DEL_ALL_EXECVE_ARGV_SHITELIST 117   /* u */
#define EXECVE_ARGV_CHECK 122               /* z */

#define ADD_WRITE_NOTIFI 87                 /* W */
#define DEL_WRITE_NOTIFI 120                /* v */
#define ADD_READ_NOTIFI 82                  /* R */
#define DEL_READ_NOTIFI 115                 /* s */
#define DEL_ALL_NOTIFI 65                   /* A */

关于 Elkeid Driver 性能

Testing Environment(VM):

CPUIntel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz 8 Core
RAM16GB
OS/KernelDebian9 / Kernel Version 4.14

Testing Load:

syscallltp
connect./runltp -f syscalls -s connect -t 5m
bind./runltp -f syscalls -s bind -t 5m
execve./runltp -f syscalls -s execve -t 5m
security_inode_create./runltp -f syscalls -s open -t 5m
ptrace./runltp -f syscalls -s ptrace -t 5m

Key kprobe Handler Testing Result(90s)

hook function nameAverage Delay(us)TP99(us)TP95(us)TP90(us)
connect_syscall_handler0.74543.50171.9041.43
connect_syscall_entry_handler0.06750.30.1630.1149
udp_recvmsg_handler9.129068.704318.535715.9528
udp_recvmsg_entry_handler0.58827.56310.78110.3665
bind_handler2.255810.05258.19967.041
bind_entry_handler0.47041.01800.82340.6739
execve_entry_handler6.926212.28249.4378.638
execve_handler15.210236.090325.927223.068
security_inode_create_pre_handler1.55237.94545.58063.1441
ptrace_pre_handler0.20390.46480.2540.228

udp_recvmsg_handler 仅工作在端口为 53 或 5353 的情况

测试原始数据: Benchmark Data

关于部署

可以使用 DKMS 或者提前编译好 ko 文件然后进行下发

  • install driver: insmod hids_driver.ko
  • remove driver: first you need kill userspace agent and rmmod hids_driver.ko

已知问题

License

Elkeid kernel module are distributed under the GNU GPLv2 license.