Linux server.thearyasamaj.org 4.18.0-553.56.1.el8_10.x86_64 #1 SMP Tue Jun 10 05:00:59 EDT 2025 x86_64
Apache
: 103.90.241.146 | : 216.73.216.222
Cant Read [ /etc/named.conf ]
5.6.40
ftpuser@mantra.thearyasamaj.org
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
src /
file_protector-1.1-1553 /
ftrace_hooks /
[ HOME SHELL ]
Name
Size
Permission
Action
audit_user.h
145
B
-rw-r--r--
fsnotify_events.c
3.87
KB
-rw-r--r--
fsnotify_events.h
353
B
-rw-r--r--
fsnotify_listener.c
9.91
KB
-rw-r--r--
fsnotify_listener.h
1.08
KB
-rw-r--r--
ftrace_events.c
15.23
KB
-rw-r--r--
ftrace_events.h
625
B
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : ftrace_events.c
/** @file ftrace_events.c @brief Events acquired via ftrace @details Copyright (c) 2024 Acronis International GmbH @author Bruce Wang (bruce.wang@acronis.com) @since $Id: $ */ #include "ftrace_hooks/ftrace_events.h" #ifdef HAVE_FTRACE_OPS_FL_SAVE_REGS #ifdef KERNEL_MOCK #include <mock/mock.h> #endif #include <linux/fs.h> #include <linux/file.h> #include <linux/fcntl.h> #include <linux/ftrace.h> #include <linux/fsnotify.h> #include <linux/namei.h> #include <linux/skbuff.h> #include <linux/types.h> #include <net/netlink.h> #include "audit_user.h" #include "compat.h" #include "debug.h" #include "exec_event.h" #include "exit_event.h" #include "file_contexts.h" #include "file_key_tools.h" #include "fsnotify_events.h" #include "fsnotify_listener.h" #include "fork_event.h" #include "fs_event.h" #include "lsm_hooks/lsm_common.h" #include "memory.h" #include "message.h" #include "path_tools.h" #include "si_size.h" #include "si_templates.h" #include "si_writer_common.h" #include "syscall_common.h" #include "task_tools.h" #if 0 FSNOTIFY_V1 // version <= 5.8: static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, const struct qstr *old_name, int isdir, struct inode *target, struct dentry *moved) { fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie); fsnotify_name(new_dir, new_dir_mask, source, new_name, fs_cookie); } static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) { fsnotify_dirent(inode, dentry, FS_CREATE); } static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry) { fsnotify_dirent(dir, dentry, FS_DELETE); } static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, __u32 mask) { fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0); } static inline void fsnotify_name(struct inode *dir, __u32 mask, struct inode *child, const struct qstr *name, u32 cookie) { fsnotify(dir, mask, child, FSNOTIFY_EVENT_INODE, name, cookie); } int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, const struct qstr *name, u32 cookie); #################### FSNOTIFY_V2 // 5.8 < version < 5.16 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, const struct qstr *old_name, int isdir, struct inode *target, struct dentry *moved) { fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie); fsnotify_name(new_dir, new_dir_mask, source, new_name, fs_cookie); } static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) { fsnotify_dirent(inode, dentry, FS_CREATE); } static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry) { fsnotify_dirent(dir, dentry, FS_DELETE); } static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, __u32 mask) { fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0); } static inline void fsnotify_name(struct inode *dir, __u32 mask, struct inode *child, const struct qstr *name, u32 cookie) { fsnotify(mask, child, FSNOTIFY_EVENT_INODE, dir, name, NULL, cookie); } int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, const struct qstr *file_name, struct inode *inode, u32 cookie); ########### FSNOTIFY_V3 (or V2) // version >= 5.16 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, const struct qstr *old_name, int isdir, struct inode *target, struct dentry *moved) { fsnotify_name(old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_dir, old_name, fs_cookie); fsnotify_name(new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_dir, new_name, fs_cookie); } static inline void fsnotify_delete(struct inode *dir, struct inode *inode, struct dentry *dentry) { fsnotify_name(mask, inode, FSNOTIFY_EVENT_INODE, dir, &dentry->d_name, 0); } static inline void fsnotify_create(struct inode *dir, struct dentry *dentry) { fsnotify_dirent(dir, dentry, FS_CREATE); } static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, __u32 mask) { fsnotify_name(mask, dentry, FSNOTIFY_EVENT_DENTRY, dir, &dentry->d_name, 0); } static inline int fsnotify_name(__u32 mask, const void *data, int data_type, struct inode *dir, const struct qstr *name, u32 cookie) { return fsnotify(mask, data, data_type, dir, name, NULL, cookie); } int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, const struct qstr *name, struct inode *inode, u32 cookie); #endif // A more generic option would be 'regs_get_kernel_argument' but kernels have a very sparring support of it // Use the following macro for now #define GET_KERNEL_ARGUMENT0(regs) regs->di #define GET_KERNEL_ARGUMENT1(regs) regs->si #define GET_KERNEL_ARGUMENT2(regs) regs->dx #define GET_KERNEL_ARGUMENT3(regs) regs->cx #define GET_KERNEL_ARGUMENT4(regs) regs->r8 #define GET_KERNEL_ARGUMENT5(regs) regs->r9 #define GET_KERNEL_ARGUMENT(regs, num) GET_KERNEL_ARGUMENT##num(regs) static void fsnotify_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { uint32_t mask; const void *data; int data_type; (void) ip; (void) parent_ip; (void) op; if (!HOOK_PROLOG()) return; #ifdef FSNOTIFY_MASK_SECOND mask = GET_KERNEL_ARGUMENT(regs, 1); data = (const void*)GET_KERNEL_ARGUMENT(regs, 2); data_type = (int) GET_KERNEL_ARGUMENT(regs, 3); #else mask = GET_KERNEL_ARGUMENT(regs, 0); data = (const void*)GET_KERNEL_ARGUMENT(regs, 1); data_type = (int) GET_KERNEL_ARGUMENT(regs, 2); #endif handle_fsnotify_event(mask, data, data_type); HOOK_EPILOG(); } static void exec_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { struct task_struct* tsk = (struct task_struct *)GET_KERNEL_ARGUMENT(regs, 0); (void) ip; (void) parent_ip; (void) op; if (!HOOK_PROLOG()) { return; } exec_event(tsk); HOOK_EPILOG(); } static void exit_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { struct task_struct* tsk = (struct task_struct *)GET_KERNEL_ARGUMENT(regs, 0); (void) ip; (void) parent_ip; (void) op; if (!HOOK_PROLOG()) { return; } exit_event(tsk); HOOK_EPILOG(); } static void fork_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { struct task_struct* tsk = (struct task_struct *)GET_KERNEL_ARGUMENT(regs, 0); (void) ip; (void) parent_ip; (void) op; if (!HOOK_PROLOG()) { return; } fork_event(tsk); HOOK_EPILOG(); } static const uint8_t k_login_logout_fields[] = { SI_COMMON_FIELDS, FP_SI_PI_OBJECT_NAME, FP_SI_PI_FLAGS }; static void audit_handle_msg(struct sk_buff* skb, struct nlmsghdr *nlh) { u16 msg_type = nlh->nlmsg_type; (void) skb; if (msg_type == AUDIT_USER_LOGIN || msg_type == AUDIT_USER_LOGOUT) { int msg_len = nlmsg_len(nlh); msg_t* msg; size_t msg_size; uint64_t event_uid; SiSizedString data; uint64_t combined_mask; task_info_t* task_info; if (msg_len < 2) return; combined_mask = transport_global_get_combined_mask(); if (!(combined_mask & MSG_TYPE_TO_EVENT_MASK(FP_SI_OT_NOTIFY_LOGIN_LOGOUT))) return; { transport_ids_t ids; transport_global_get_ids(&ids); task_info = task_info_map_get(current); refresh_task(task_info, &ids); // not skipping event - always send login/logout events } data.value = (const char*) NLMSG_DATA(nlh); data.length = strnlen(data.value, msg_len); msg_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_login_logout_fields) + data.length; msg = msg_new(FP_SI_OT_NOTIFY_LOGIN_LOGOUT, 0, SI_CT_POST_CALLBACK, make_unique_pid(current), msg_size); if (msg) { event_uid = transport_global_sequence_next(); { si_property_writer_t writer; si_event_writer_init(&writer, &msg->event, msg_size); si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info); si_property_writer_write_object_name(&writer, data); si_property_writer_write_flags(&writer, msg_type); si_event_writer_finalize(&msg->event, &writer); } send_msg_async_unref(msg); } if (task_info) task_info_put(task_info); } } static void audit_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { struct sk_buff* skb = (struct sk_buff*)GET_KERNEL_ARGUMENT(regs, 0); struct nlmsghdr *nlh; int len; (void) ip; (void) parent_ip; (void) op; nlh = nlmsg_hdr(skb); len = skb->len; while (NLMSG_OK(nlh, len)) { audit_handle_msg(skb, nlh); nlh = NLMSG_NEXT(nlh, len); } } static void pre_write(const struct path *path, int flags, loff_t offset, size_t count) { transport_ids_t transport_ids; task_info_t* task_info; file_context_info_t file_context_info = {0}; const uint64_t generatedEventsMask = MSG_TYPE_TO_EVENT_MASK(FP_SI_OT_SYNC_FILE_PRE_WRITE); if (!(transport_global_get_combined_mask() & generatedEventsMask) || transport_is_control_tgid(current->tgid)) { return; } task_info = task_info_map_get(current); if (!task_info) return; transport_global_get_ids(&transport_ids); refresh_task(task_info, &transport_ids); if (task_info_can_skip(task_info, &transport_ids, generatedEventsMask)) goto err_skipped; if (make_file_context_info(&file_context_info, path, flags, offset, offset + count, READ_ONCE(task_info->pid_version)) && check_write_cache(&transport_ids, &file_context_info, FILE_CONTEXT_WRITE_TABLE)) goto err_skipped; (void) fs_event_pre_write(task_info, flags, offset, count, path, &file_context_info.msg_info); err_skipped: task_info_put(task_info); } static void pre_read(const struct path *path, int flags, loff_t offset, size_t count) { transport_ids_t transport_ids; task_info_t* task_info; file_key_t key; const uint64_t generatedEventsMask = MSG_TYPE_TO_EVENT_MASK(FP_SI_OT_NOTIFY_FILE_FULL_READ); if (!(transport_global_get_combined_mask() & generatedEventsMask) || transport_is_control_tgid(current->tgid)) { return; } task_info = task_info_map_get(current); if (!task_info) return; transport_global_get_ids(&transport_ids); refresh_task(task_info, &transport_ids); if (task_info_can_skip(task_info, &transport_ids, generatedEventsMask)) goto err_skipped; { file_context_info_t file_context_info = {0}; if (make_file_context_info(&file_context_info, path, flags, offset, offset + count, READ_ONCE(task_info->pid_version)) && check_and_update_read_cache(&transport_ids, &file_context_info)) { goto err_skipped; } } make_key(&key, path); fs_event_pre_full_read(task_info, &key, flags, offset, count); err_skipped: task_info_put(task_info); } static void rw_verify_area_entry_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { int read_write = (int)GET_KERNEL_ARGUMENT(regs, 0); bool write = WRITE == read_write; bool read = READ == read_write; struct file *file = (struct file *)GET_KERNEL_ARGUMENT(regs, 1); const loff_t *ppos = (const loff_t *)GET_KERNEL_ARGUMENT(regs, 2); size_t count = (size_t)GET_KERNEL_ARGUMENT(regs, 3); loff_t pos; (void) ip; (void) parent_ip; (void) op; if (!file || !ppos) return; if (!read && !write) return; #ifdef FMODE_NONOTIFY if (file->f_mode & FMODE_NONOTIFY) return; #endif pos = *ppos; // I am not even going to consider these weird cases // rw_verify_area will check for those and I will do so too if (pos < 0) return; if ((ssize_t) count < 0) return; if ((loff_t) (pos + count) < 0) return; if (!file_is_valid(file)) return; if (!HOOK_PROLOG()) return; if (write) pre_write(&file->f_path, file->f_flags, pos, count); if (read) pre_read(&file->f_path, file->f_flags, pos, count); HOOK_EPILOG(); } typedef struct { struct ftrace_ops ops; unsigned long fn; const char* name; bool registered; } fp_probe_t; // !!! These must align exactly with ftrace_post_event_type_t !!! static fp_probe_t g_probes[] = { { .ops = { .func = (ftrace_func_t) fsnotify_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, .fn = (unsigned long) fsnotify, .name = NULL, .registered = false, }, { .ops = { .func = (ftrace_func_t) exec_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, .fn = 0, .name = "proc_exec_connector", .registered = false, }, { .ops = { .func = (ftrace_func_t) exit_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, .fn = 0, .name = "proc_exit_connector", .registered = false, }, { .ops = { .func = (ftrace_func_t) fork_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, .fn = 0, .name = "proc_fork_connector", .registered = false, }, { .ops = { .func = (ftrace_func_t) audit_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, .fn = 0, .name = "audit_receive", .registered = false, }, { .ops = { .func = (ftrace_func_t) rw_verify_area_entry_handler, .flags = FTRACE_OPS_FL_SAVE_REGS, }, // rw_verify_area is a public symbol in modern kernels but not in the older ones. // TODO: 'rw_verify_area' misses 'remap_verify_area' case so cloning is not handled. // Perhaps a simple solution could be hooking the clone functions like // 'vfs_clone_file_range' and 'vfs_dedupe_file_range_one'? // themselves? #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) .fn = (unsigned long) rw_verify_area, .name = NULL, #else .fn = 0, .name = "rw_verify_area", #endif .registered = false, }, }; void register_ftrace_post_events(void) { int i = 0; for (; i < (int) ARRAY_SIZE(g_probes); i++) { fp_probe_t* probe = &g_probes[i]; struct ftrace_ops *ops = &probe->ops; int ret; #ifdef HAVE_FSNOTIFY_PUBLIC_API if (i == FTRACE_POST_EVENT_FSNOTIFY) { IPRINTF("fsnotify public API is used instead of ftrace"); continue; } #endif if (probe->name) { probe->fn = compat_kallsyms_lookup_name(probe->name); if (!probe->fn) { EPRINTF("Failed to find %s", probe->name); continue; } DPRINTF("%s -> %lu", probe->name, probe->fn); } ret = ftrace_set_filter_ip(ops, probe->fn, 0, 0); if (ret < 0) { EPRINTF("Failed to set filter ip"); continue; } ret = register_ftrace_function(ops); if (ret < 0) { EPRINTF("Failed to register ftrace"); continue; } IPRINTF("Planted ftrace %ps", (void*) probe->fn); g_probes[i].registered = true; } } void unregister_ftrace_post_events(void) { int i = 0; for (; i < (int) ARRAY_SIZE(g_probes); i++) { if (g_probes[i].registered) { fp_probe_t* probe = &g_probes[i]; struct ftrace_ops *ops = &probe->ops; IPRINTF("Remove ftrace for %ps", (void*) probe->fn); unregister_ftrace_function(ops); ftrace_set_filter_ip(ops, probe->fn, 1, 0); g_probes[i].registered = false; } } } bool ftrace_post_event_have(ftrace_post_event_type_t ev) { if (ev == FTRACE_POST_EVENT_FSNOTIFY && fsnotify_events_listener_registered()) return true; return g_probes[ev].registered; } #else void register_ftrace_post_events(void) { } void unregister_ftrace_post_events(void) { } bool ftrace_post_event_have(ftrace_post_event_type_t ev) { return false; } #endif
Close