h(  ) ($6;EbBLkfu�_l� ''8;DUFKV3Dd#,?ANk&5G$/(5M\^�ms����Sb�,;R''6c2I�!\����kx�Ve�[i��Me�IYO7:nOL~�Kr�qrv�I:�BM�y��s}r��K����x)1�6@r*2�89ma��&��'ti������{~#������t)1�2<�0:^5�W.uFzQ/u}�v��vv�u��U37yDJeEJo(/�5Ds'1�:Jlu�iy�iy�hw�1;:S`^BMLOQQn,4�7C�8C�>Lfe�]k�[i�Zg��IW�LZ�EP;,.��Tc�q(0) G,/]/1����w�r��l&-t*3�<<�u��#����j&.u��J68\8?"#$%&'()*+,-./0 ! 
Notice: Undefined index: dl in /var/www/html/web/simple.mini.php on line 1
403WebShell
403Webshell
Server IP : 10.254.12.21  /  Your IP : 10.254.12.21
Web Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.6.40
System : Linux arit.skru.ac.th 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64
User : apache ( 48)
PHP Version : 5.6.40
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/opt/eset/efs/eventd/eset_rtp/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/opt/eset/efs/eventd/eset_rtp/ertp_handlers.c
/*
 * eset_rtp (ESET Real-time file system protection module)
 * Copyright (C) 1992-2021 ESET, spol. s r.o.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * In case of any questions, you can contact us at ESET, spol. s r.o., Einsteinova 24, 851 01 Bratislava, Slovakia.
 */

/* ftrace symbols are undefined for modules, so turn this off to avoid errors */
#undef CONFIG_FTRACE_SYSCALLS

#include "ertp_handlers.h"

#ifndef ERTP_KERNEL_USES_SYSCALL_WRAPPER

/* syscall signature definitions */
typedef asmlinkage long (*sys_open_t)(const char * /*filename*/,
						int /*flags*/, umode_t /*mode*/);

typedef asmlinkage long (*sys_openat_t)(int /*dfd*/, const char * /*filename*/,
						int /*flags*/, umode_t /*mode*/);

typedef asmlinkage long (*sys_close_t)(unsigned int /*fd*/);

typedef asmlinkage long (*sys_exit_t)(int /*error_code*/);
typedef sys_exit_t sys_exit_group_t;

typedef asmlinkage long (*sys_dup2_t)(unsigned int /*oldfd*/, unsigned int /*newfd*/);

typedef asmlinkage long (*sys_dup3_t)(unsigned int /*oldfd*/, unsigned int /*newfd*/,
	int /*flags*/);

typedef asmlinkage long (*sys_unlink_t)(const char __user * /*pathname*/);

typedef asmlinkage long (*sys_unlinkat_t)(int /*dfd*/, const char __user * /*pathname*/,
	int /*flag*/);

typedef asmlinkage long (*sys_rename_t)(const char __user * /*oldname*/,
	const char __user * /*newname*/);

typedef asmlinkage long (*sys_renameat_t)(int /*oldfd*/, const char __user * /*oldname*/,
	int /*newdfd*/, const char __user * /*newname*/);

#	if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
typedef asmlinkage long (*sys_renameat2_t)(int /*oldfd*/, const char __user * /*oldname*/,
	int /*newdfd*/, const char __user * /*newname*/, unsigned int /*flags*/);
#	endif

typedef asmlinkage long (*sys_mmap_t)(unsigned long /*addr*/, unsigned long  /*len*/,
	unsigned long /*prot*/, unsigned long /*flags*/,
	unsigned long /*fd*/, unsigned long /*pgoff*/);

#endif /* ERTP_KERNEL_USES_SYSCALL_WRAPPER */

/* counter and wait queue for safe module unload */
atomic_t ertp_running_syscalls_counter = ATOMIC_INIT(0);
DECLARE_WAIT_QUEUE_HEAD(ertp_syscall_handlers_unregister_wait);

/***************************** SYSCALL HANDLERS ******************************/

/***************************** sys_open*() handlers **************************/

static long check_open_int(long fd, const char __user *filename);


ERTP_SYSCALL_HANDLER3(open, const char __user *, filename,
		int, flags, umode_t, mode)
{
	long fd = CALL_ORIG3(open, filename, flags, mode);
	return check_open_int(fd, filename);
}

ERTP_SYSCALL_HANDLER4(openat, int, dfd, const char __user *, filename,
		int, flags, umode_t, mode)
{
	long fd = CALL_ORIG4(openat, dfd, filename, flags, mode);
	return check_open_int(fd, filename);
}

/***************************** sys_close() handler ************************/

static void check_close(unsigned int fd)
{
	struct file *file = fget(fd);

	if (likely(file)) {
		ertp_check_close(file);
		fput(file);
	} else {
		ertp_pr_debug("cannot get file object for file descriptor %d", fd);
	}
}

ERTP_SYSCALL_HANDLER1(close, unsigned int, fd)
{
	check_close(fd);
	return CALL_ORIG1(close, fd);
}

static long check_open_int(long fd, const char __user *filename)
{
	struct file *file;
#ifdef ERTP_DEBUG
	char *kname = ertp_getname(filename);
	char *name = IS_ERR_OR_NULL(kname) ? ERPT_UNKONWN : kname;
#endif /* ERTP_DEBUG */

	if (IS_ERR_VALUE(fd))
		return fd;

	file = fget(fd);
	if (unlikely(file == NULL))
		return fd;

	if (ertp_check_open(file) == ERTP_DENIED) {
		ertp_pr_debug("open(%s) denied by scanner", name);

		if (CALL_ORIG1(close, fd) != 0) {
			ertp_pr_warning("error closing file");
		}

		fd = -EPERM;
	}
#ifdef ERTP_DEBUG
	ertp_putname(kname);
#endif
	fput(file);
	return fd;
}

/***************************** sys_exit*() handlers ************************/

enum ertp_flt_rv ertp_check_all_open_files(enum ertp_flt_rv (*file_check_fn)(const struct file *))
{
	unsigned         fd, max_fds;
	enum ertp_flt_rv rv = ERTP_CONTINUE;

	ertp_pr_debug("checking open files of process %ld", (long)current->pid);

	rcu_read_lock();
	max_fds = files_fdtable(current->files)->max_fds;
	rcu_read_unlock();

	/* iterate through all files and scan them */
	for (fd = 0; fd < max_fds; fd++) {
		struct file *file = fget(fd);

		if (likely(file)) {
			enum ertp_flt_rv check_result = file_check_fn(file);
			fput(file);
			if (check_result != ERTP_CONTINUE) {
				rv = ERTP_DENIED;
			}
		}
	}

	return rv;
}

ERTP_SYSCALL_HANDLER1(exit, int, error_code)
{
	ertp_check_all_open_files(ertp_check_close);

	/* exit does not return, so call helper manually to decrease counter */
	ertp_handler_end();
	return CALL_ORIG1(exit, error_code);
}

ERTP_SYSCALL_HANDLER1(exit_group, int, error_code)
{
	ertp_check_all_open_files(ertp_check_close);

	/* exit_group does not return, so call helper manually to decrease counter */
	ertp_handler_end();
	return CALL_ORIG1(exit_group, error_code);
}

/***************************** sys_dup*() handlers ************************/

/**
 * If newfd is an opened file, dup2 and dup3 will close it, so we need to catch these syscalls.
 */
ERTP_SYSCALL_HANDLER2(dup2, unsigned int, oldfd, unsigned int, newfd)
{
	check_close(newfd);
	return CALL_ORIG2(dup2, oldfd, newfd);
}

ERTP_SYSCALL_HANDLER3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
{
	check_close(newfd);
	return CALL_ORIG3(dup3, oldfd, newfd, flags);
}

/***************************** sys_unlink*() handlers ************************/
ERTP_SYSCALL_HANDLER1(unlink, const char __user *, pathname)
{
	int error;
	long ret;
	struct path path;

	error = user_path_at(AT_FDCWD, pathname, 0, &path);
	ret = CALL_ORIG1(unlink, pathname);

	if (error) {
		return ret;
	} else if (!ret) {
		ertp_remove_notify(&path);
	}

	path_put(&path);
	return ret;
}

ERTP_SYSCALL_HANDLER3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
{
	int error;
	long ret;
	struct path path;

	// directories are not cached
	if (flag == AT_REMOVEDIR) {
		return CALL_ORIG3(unlinkat, dfd, pathname, flag);
	}

	error = user_path_at(dfd, pathname, 0, &path);
	ret = CALL_ORIG3(unlinkat, dfd, pathname, flag);

	if (error) {
		return ret;
	} else if (!ret) {
		ertp_remove_notify(&path);
	}

	path_put(&path);
	return ret;
}

/***************************** sys_rename*() handlers ************************/
/* sys_rename*() can remove file at newname path if there already exists a file */

ERTP_SYSCALL_HANDLER2(rename, const char __user *, oldname, const char __user *, newname)
{
	int error;
	long ret;
	struct path path;

	error = user_path_at(AT_FDCWD, newname, 0, &path);
	ret = CALL_ORIG2(rename, oldname, newname);

	if (error) {
		return ret;
	} else if (!ret) {
		ertp_remove_notify(&path);
	}

	path_put(&path);
	return ret;
}

ERTP_SYSCALL_HANDLER4(renameat, int, olddfd, const char __user *, oldname,
		int, newdfd, const char __user *, newname)
{
	int error;
	long ret;
	struct path path;

	error = user_path_at(newdfd, newname, 0, &path);
	ret = CALL_ORIG4(renameat, olddfd, oldname, newdfd, newname);

	if (error) {
		return ret;
	} else if (!ret) {
		ertp_remove_notify(&path);
	}

	path_put(&path);
	return ret;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
ERTP_SYSCALL_HANDLER5(renameat2, int, olddfd, const char __user *, oldname,
		int, newdfd, const char __user *, newname, unsigned int, flags)
{
	int error;
	long ret;
	struct path path;

	error = user_path_at(newdfd, newname, 0, &path);
	ret = CALL_ORIG5(renameat2, olddfd, oldname, newdfd, newname, flags);

	if (error) {
		return ret;
	} else if (!ret) {
		ertp_remove_notify(&path);
	}

	path_put(&path);
	return ret;
}
#endif

ERTP_SYSCALL_HANDLER6(mmap, unsigned long, addr, unsigned long, len,
		unsigned long, prot, unsigned long, flags,
		unsigned long, fd, unsigned long, pgoff)
{
	struct file *file;


	// MAP_ANONYMOUS and fd == -1 map just empty memory (no file to scan), skip these calls
	// fd has been already scanned on open, now we scan it only if PROT_EXEC is used as exec event
	if ((flags & MAP_ANONYMOUS) || (fd == -1) || !(prot & PROT_EXEC))
		return CALL_ORIG6(mmap, addr, len, prot, flags, fd, pgoff);

	file = fget(fd);
	if (!file)
		return -EBADF;

	if (ertp_check_exec(file) != ERTP_CONTINUE) {
		ertp_pr_info("mmap denied by scanner");
		fput(file);
		return -EPERM;
	}
	fput(file);

	return CALL_ORIG6(mmap, addr, len, prot, flags, fd, pgoff);
}

/************************ syscall handlers management ************************/

#define ERTP_SYS_HOOK_REGISTER(syscall) do { \
	if ((rv = ertp_sys_hook_register(ERTP_SYSCALL_##syscall, ERTP_HANDLER_64_FN(syscall), ERTP_HANDLER_IA32_FN(syscall), NULL)) != 0) { \
		ertp_pr_error("syscall hook registration failed"); \
		return rv; \
	} \
} while (0)


static int register_handlers(void)
{
	int rv;

	ERTP_SYS_HOOK_REGISTER(open);
	ERTP_SYS_HOOK_REGISTER(openat);
	ERTP_SYS_HOOK_REGISTER(close);
	ERTP_SYS_HOOK_REGISTER(exit);
	ERTP_SYS_HOOK_REGISTER(exit_group);
	ERTP_SYS_HOOK_REGISTER(dup2);
	ERTP_SYS_HOOK_REGISTER(dup3);
	ERTP_SYS_HOOK_REGISTER(unlink);
	ERTP_SYS_HOOK_REGISTER(unlinkat);
	ERTP_SYS_HOOK_REGISTER(rename);
	ERTP_SYS_HOOK_REGISTER(renameat);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
	ERTP_SYS_HOOK_REGISTER(renameat2);
#endif

	if ((rv = ertp_sys_hook_register(ERTP_SYSCALL_mmap, ERTP_HANDLER_64_FN(mmap), NULL, NULL)) != 0) {
		ertp_pr_error("mmap() syscall hook registration failed");
		return rv;
	}

	return 0;
}

#undef ERTP_SYS_HOOK_REGISTER

static void ertp_wait_for_running_syscalls(void)
{
	msleep(500); // wait a bit until all our running syscalls are hopefully counted

	/* now we want to be woken up, when last syscall is finished */
	atomic_dec(&ertp_running_syscalls_counter);

	ertp_pr_debug("Waiting for %d caught syscalls", atomic_read(&ertp_running_syscalls_counter));
	wait_event(ertp_syscall_handlers_unregister_wait, atomic_read(&ertp_running_syscalls_counter) == 0);

	msleep(500); // wait a bit until all our running syscalls are hopefully finished
}

int ertp_handlers_init(uintptr_t k32, uintptr_t k64)
{
	int rv;

	/* mute waking-up signal on the last running syscall */
	/* zero will be again reachable during handlers deinit, when we wait for the signal from last syscall */
	atomic_inc(&ertp_running_syscalls_counter);

	if ((rv = ertp_sys_hooks_init(k32, k64)) != 0) {
		return rv;
	}

	if ((rv = ertp_init_execve_handlers()) != 0) {
		return rv;
	}

	if ((rv = register_handlers()) != 0) {
		goto err;
	}

	ertp_pr_info("registered syscall handlers");

	return 0;

err:
	ertp_handlers_deinit();

	return rv;
}

void ertp_handlers_deinit(void)
{
	ertp_deinit_execve_handlers();
	ertp_sys_hooks_unload();
	ertp_wait_for_running_syscalls();
	ertp_pr_info("unregistered syscall handlers");
}

Youez - 2016 - github.com/yon3zu
LinuXploit