# bpf study - xdr sensor record. - footprint -> CVE pattern. - system call -> Capture the "system call". - event type : Check how many events need to send to "seleniumd"? ```clike= enum XDR_EVENT_TYPE { XDR_EVENT_NONE = 0; XDR_EVENT_PROCESS = 1; XDR_EVENT_FILE = 2; ... } ``` - Target - Capture "system call" or "CVE pattern" in appilication. - Decode the message with "protocol buffer" and then send it to "seleniumd" - First of all, i'd like to capture the "system call", e.g: "open file" event send it to daemon. --- ### XDR type ```clike typedef enum _XDR_EVENT_TYPE { XDR_EVENT_TYPE_XDR_EVENT_NONE = 0, XDR_EVENT_TYPE_XDR_EVENT_PROCESS = 1, XDR_EVENT_TYPE_XDR_EVENT_FILE = 2, XDR_EVENT_TYPE_XDR_EVENT_CONNECTION = 3, XDR_EVENT_TYPE_XDR_EVENT_DNS = 4, XDR_EVENT_TYPE_XDR_EVENT_ACCOUNT = 6, XDR_EVENT_TYPE_XDR_EVENT_INTERNET = 7, XDR_EVENT_TYPE_XDR_EVENT_MODIFIED_PROCESS = 8, /* The name may be confusing. We use it for access other processes either write or read (i.e. XDR_EVENT_ACCESS_PROCESS) */ XDR_EVENT_TYPE_XDR_EVENT_MEMORY = 13, /* for memory specific operation events like modify memory, change memory permission and read memory, etc. */ XDR_EVENT_TYPE_XDR_EVENT_BM = 14 } XDR_EVENT_TYPE; typedef enum _XDR_ACCESS_TYPE { XDR_ACCESS_TYPE_XDR_NONE = 0, XDR_ACCESS_TYPE_XDR_PROCESS_OPEN = 1, XDR_ACCESS_TYPE_XDR_PROCESS_CREATE = 2, XDR_ACCESS_TYPE_XDR_PROCESS_TERMINATE = 3, XDR_ACCESS_TYPE_XDR_PROCESS_LOAD_IMAGE = 4, XDR_ACCESS_TYPE_XDR_PROCESS_EXECUTE = 5, /* the subject process execute the target file (target_hash_id == file_meta) (i.e. Pre-XDR_PROCESS_CREATE) */ XDR_ACCESS_TYPE_XDR_PROCESS_CONNECT = 6, /* the subject process connects to the target process via IPC, etc. (target_hash_id == process_meta) */ XDR_ACCESS_TYPE_XDR_PROCESS_TRACME = 7, /* Linux specific - the subject process asks the target process to trace itself (target_hash_id == process_meta) */ XDR_ACCESS_TYPE_XDR_FILE_CREATE = 101, XDR_ACCESS_TYPE_XDR_FILE_OPEN = 102, XDR_ACCESS_TYPE_XDR_FILE_DELETE = 103, XDR_ACCESS_TYPE_XDR_FILE_SET_SECURITY = 104, XDR_ACCESS_TYPE_XDR_FILE_COPY = 105, XDR_ACCESS_TYPE_XDR_FILE_MOVE = 106, XDR_ACCESS_TYPE_XDR_FILE_CLOSE = 107, XDR_ACCESS_TYPE_XDR_FILE_MODIFY_TIMESTAMP = 108, XDR_ACCESS_TYPE_XDR_FILE_MODIFY = 109, XDR_ACCESS_TYPE_XDR_CONNECTION_CONNECT = 201, XDR_ACCESS_TYPE_XDR_CONNECTION_LISTEN = 202, XDR_ACCESS_TYPE_XDR_CONNECTION_CONNECT_INBOUND = 203, XDR_ACCESS_TYPE_XDR_CONNECTION_CONNECT_OUTBOUND = 204, XDR_ACCESS_TYPE_XDR_DNS_QUERY = 301, XDR_ACCESS_TYPE_XDR_ACCOUNT_ADD = 501, XDR_ACCESS_TYPE_XDR_ACCOUNT_DELETE = 502, XDR_ACCESS_TYPE_XDR_ACCOUNT_IMPERSONATE = 503, XDR_ACCESS_TYPE_XDR_ACCOUNT_MODIFY = 504, XDR_ACCESS_TYPE_XDR_INTERNET_OPEN = 601, XDR_ACCESS_TYPE_XDR_INTERNET_CONNECT = 602, XDR_ACCESS_TYPE_XDR_INTERNET_DOWNLOAD = 603, XDR_ACCESS_TYPE_XDR_MODIFIED_PROCESS_WRITE_MEMORY = 702, XDR_ACCESS_TYPE_XDR_MODIFIED_PROCESS_WRITE_PROCESS = 703, /* Generic modification to a process (i.e. not limited to write memory) (target_hash_id == modified_process_meta) */ XDR_ACCESS_TYPE_XDR_MODIFIED_PROCESS_READ_PROCESS = 704, /* Generic reading a process (target_hash_id == modified_process_meta) */ XDR_ACCESS_TYPE_XDR_MODIFIED_PROCESS_WRITE_PROCESS_NAME = 705, /* Specific for modifying the name of a process (target_hash_id == modified_process_meta) */ XDR_ACCESS_TYPE_XDR_MEMORY_MODIFY = 1001, XDR_ACCESS_TYPE_XDR_MEMORY_MODIFY_PERMISSION = 1002, XDR_ACCESS_TYPE_XDR_MEMORY_READ = 1003, XDR_ACCESS_TYPE_XDR_BM_INVOKE = 1101, /* target_hash_id == bm_meta */ XDR_ACCESS_TYPE_XDR_BM_INVOKE_API = 1102 /* target_hash_id == api_meta */ } XDR_ACCESS_TYPE; typedef enum _XDR_CONNECTION_TYPE { XDR_CONNECTION_TYPE_XDR_CONNECTION_NONE = 0, XDR_CONNECTION_TYPE_XDR_CONNECTION_TCP = 1, XDR_CONNECTION_TYPE_XDR_CONNECTION_UDP = 2 } XDR_CONNECTION_TYPE; ``` --- ### Code references - Kernel space (`selenium.ko` driver module) - Act event utilities: `projs/lithium/kmod/selenium/src/act_event/...` - Event source (hooks): `projs/lithium/kmod/selenium/src/hook/hooks.c` - User space code - Act event utilities: - Act event (activity object): `lib/nanopb/xdr/act_event/ActEvent.h` - Event IPC helpers: `lib/nanopb/xdr/act_event/ActIPC.h` - Aggregation `seleniumd` - Daemon process: `projs/lithium/src/selenium/seleniumd/seleniumd.cpp` - Footprint generator: `projs/lithium/src/selenium/seleniumd/FootprintGenerator.cpp` - Sender example `libhe7.so` (who send network event) - `projs/helium/src/libhe7/He7Tracker.cpp` Note that we use `PbUtils` protobuf utility which wrapper `nanppb` 3rd party library. You would like to reference the test code in quark: - PbUtils: `lib/quark/src/down/util/nanopb/PbUtils.h` - unit test code: `lib/quark/unit_test/ut_util/test_nanopb_Pb2Utils.cpp` Where we had already use `libbpf`: - `projs/helium/src/libhhef/AFPService.cpp` - atom document. https://adc.github.trendmicro.com/Consumer-ATOM/atom-doc - internal wiki https://wiki.jarvis.trendmicro.com/display/MSBD/Knowledge+Sharing - tmis agent. https://adc.github.trendmicro.com/Consumer-ATOM/atom-doc/blob/master/design/soter/XDR_Sensor_Integration_-_TMIS_Agent.md - installation e.g. ```c ./install.sh -y --agent-key /path/to/agent_key --model my_name -nfq -ldp ./install.sh -y --agent-key /path/to/agent_key --model my_name -nfq -ldp n ./install.sh -y --agent-key /home/atom/agent_key --model my_name -nfq -ldp n ``` - Setup alias or PATH ```c alias atom='sudo /opt/atom/bin/atom' ``` - Start agent (currently just start it in offline mode) ```c atom start --offline+ ``` - Extract the .gpbz file with json format. ```c atom snr X stati.....gpbz -P ``` - Check the full function in command line ```bash= atom@ubuntu:~/trendmicro_iot_security_0.0.00_ubuntu_20_04_x86_64_full$ atom status Daemon status: Independent mode Features enabled: aal processing offline hips ready offline svs idle offline wrs ready independent snr ready independent bm ready offline ``` - snr - footprint log ```c { "hash_id": 1418905967374183748, "first_seen": 1661794122, "last_seen": 1661794122, "size": 0, "create_time": 1661794112, "modify_time": 1661794112, "filename": "/proc/irq/1/smp_affinity", "signers": [], "owner_sid": "0", "owner_name": "root", "group_sid": "0", "group_name": "root", "telemetry_tags": [] } ``` - statistics log ```clike= { "customer_guid": "762b48fd-15aa-4d0d-b553-060e1f9145e8", "agent_guid": "96fcbb52-64f6-2805-24d3-000c2986a502", "timestamp": 1661794651, "version": "1.0", "vehicle_id": "96fcbb52-64f6-2805-24d3-000c2986a502", "model_id": "my_name", "event_info": [ { "component": "SNR", "event_type": 102, "event_stat_type": 1, "count": 9 } ], "elapse_time": 10, "hit_critical_event": true } ``` - to do - [ ] ebpf ring buff - [ ] integrate the ebpf syscall hook to atom code base. - [ ] Send unix socket to selenium daemon. - [ ] compare the performance with kernel orca driver. - link https://hackmd.io/@st9540808/HkvPfU7Tr https://www.ebpf.top/post/bcc-to-libbpf-guid/ https://lore.kernel.org/bpf/ - kernel bpf flow -[ebpf entry from syscall](https://github.com/torvalds/linux/blob/42e66b1cc3a070671001f8a1e933a80818a192bf/kernel/bpf/syscall.c#L4899) - Porting "atom sdk" to other platform. - toolchain/ - gcc version ? - kernel-headers/ - kernel headers include? - In the submodule, git checkout -b branch, git add, git commit, - merge request the modified file to master. - In the "atom-socter/atom-sdk" reporitory, run "./update-repo.sh", run git status to check every submodule status, then update ".gitmodule" file - CPP:design pattern ![](https://i.imgur.com/qn6RYwk.png) - Design document - https://www.overleaf.com/ - https://sspai.com/post/64080 - kernel syscall - https://lwn.net/Articles/379903/ - https://www.cntofu.com/book/114/SysCall/syscall-2.md - https://lwn.net/Articles/346280/ - https://www.anquanke.com/post/id/265887 - https://zh-blog.logan.tw/2019/07/10/analyze-program-performance-with-perf-events/ ![](https://i.imgur.com/EqDoUwu.png) ![](https://i.imgur.com/SsHayPu.png) ![](https://i.imgur.com/2j47n8O.png) - tracepoint ```bash cat /sys/kernel/debug/tracing/available_events // get available trace event ``` ```c TRACE_EVENT_FN(sys_enter, TP_PROTO(struct pt_regs *regs, long id), TP_ARGS(regs, id), TP_STRUCT__entry( __field( long, id ) __array( unsigned long, args, 6 ) ), TP_fast_assign( __entry->id = id; syscall_get_arguments(current, regs, __entry->args); ), TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", __entry->id, __entry->args[0], __entry->args[1], __entry->args[2], __entry->args[3], __entry->args[4], __entry->args[5]), syscall_regfunc, syscall_unregfunc ); ```c - sched_process_exec - __data_loc char[] filename; - pid_t pid; - pid_t old_pid; - sys_exit_execve - int __syscall_nr; - long ret; - sys_enter_execve - int __syscall_nr; - const char* file_name; - const char *const* argv; - const char *const * envp; ```