ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ืฉืœื•ื, ื”ื‘ืจ! ื”ื™ื•ื ืื ื™ ืจื•ืฆื” ืœื“ื‘ืจ ืขืœ ืื™ืš ืืชื” ื™ื›ื•ืœ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ืžืคื ื™ ื”ืชืงืคื•ืช ืฉืœ ืชื•ืงืคื™ื ื‘-macOS. ืœื“ื•ื’ืžื”, ื–ื” ืฉื™ืžื•ืฉื™ ืขื‘ื•ืจ ืื ื˜ื™ ื•ื™ืจื•ืก ืื• ืžืขืจื›ืช ื’ื™ื‘ื•ื™, ื‘ืžื™ื•ื—ื“ ืžื›ื™ื•ื•ืŸ ืฉืชื—ืช macOS ื™ืฉื ืŸ ืžืกืคืจ ื“ืจื›ื™ื "ืœื”ืจื•ื’" ืชื”ืœื™ืš. ืงืจืื• ืขืœ ื–ื” ื•ืขืœ ืฉื™ื˜ื•ืช ื”ื’ื ื” ืžืชื—ืช ืœื—ืชื•ืš.

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ื”ื“ืจืš ื”ืงืœืืกื™ืช "ืœื”ืจื•ื’" ืชื”ืœื™ืš

ื“ืจืš ื™ื“ื•ืขื” "ืœื”ืจื•ื’" ืชื”ืœื™ืš ื”ื™ื ืœืฉืœื•ื— ืื•ืช SIGKILL ืœืชื”ืœื™ืš. ื“ืจืš bash ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืœ"kill -SIGKILL PID" ื”ืกื˜ื ื“ืจื˜ื™ ืื• "pkill -9 NAME" ื›ื“ื™ ืœื”ืจื•ื’. ื”ืคืงื•ื“ื” "ื”ืจื•ื’" ื™ื“ื•ืขื” ืขื•ื“ ืžื™ืžื™ UNIX ื•ื”ื™ื ื–ืžื™ื ื” ืœื ืจืง ื‘-macOS, ืืœื ื’ื ื‘ืžืขืจื›ื•ืช ืื—ืจื•ืช ื“ืžื•ื™ื•ืช UNIX.

ื‘ื“ื™ื•ืง ื›ืžื• ื‘ืžืขืจื›ื•ืช ื“ืžื•ื™ื•ืช UNIX, macOS ืžืืคืฉืจ ืœื™ื™ืจื˜ ื›ืœ ืื•ืชื•ืช ืœืชื”ืœื™ืš ืžืœื‘ื“ ืฉื ื™ื™ื - SIGKILL ื•-SIGSTOP. ืžืืžืจ ื–ื” ื™ืชืžืงื“ ื‘ืขื™ืงืจ ื‘ืื•ืช SIGKILL ื›ืื•ืช ื”ื’ื•ืจื ืœืชื”ืœื™ืš ืœื”ืจื•ื’.

ืคืจื˜ื™ macOS

ื‘-macOS, ืงืจื™ืืช ืžืขืจื›ืช ื”ื”ืจื•ื’ ื‘ืงืจื ืœ ืฉืœ XNU ืงื•ืจืืช ืœืคื•ื ืงืฆื™ื” psignal(SIGKILL,...). ื‘ื•ืื• ื ื ืกื” ืœืจืื•ืช ืื™ืœื• ืคืขื•ืœื•ืช ืžืฉืชืžืฉ ืื—ืจื•ืช ื‘ืžืจื—ื‘ ื”ืžืฉืชืžืฉ ื™ื›ื•ืœื•ืช ืœื”ื™ืงืจื ืขืœ ื™ื“ื™ ืคื•ื ืงืฆื™ื™ืช psignal. ื‘ื•ื ื ืฉื›ื” ืืช ื”ืงืจื™ืื•ืช ืœืคื•ื ืงืฆื™ื™ืช psignal ื‘ืžื ื’ื ื•ื ื™ื ื”ืคื ื™ืžื™ื™ื ืฉืœ ื”ืงืจื ืœ (ืื ื›ื™ ื”ื ืขืฉื•ื™ื™ื ืœื”ื™ื•ืช ืœื ื˜ืจื™ื•ื•ื™ืืœื™ื™ื, ืื‘ืœ ื ืฉืื™ืจ ืื•ืชื ืœืžืืžืจ ืื—ืจ ๐Ÿ™‚ - ืื™ืžื•ืช ื—ืชื™ืžื”, ืฉื’ื™ืื•ืช ื–ื™ื›ืจื•ืŸ, ื˜ื™ืคื•ืœ ื‘ื™ืฆื™ืื”/ืกื™ื•ื, ื”ืคืจื•ืช ืฉืœ ื”ื’ื ื” ืขืœ ืงื‘ืฆื™ื, ื•ื›ื• '

ื ืชื—ื™ืœ ืืช ื”ืกืงื™ืจื” ืขื ื”ืคื•ื ืงืฆื™ื” ื•ืงืจื™ืืช ื”ืžืขืจื›ืช ื”ืžืชืื™ืžื” terminate_with_payload. ื ื™ืชืŸ ืœืจืื•ืช ืฉื‘ื ื•ืกืฃ ืœ-kill call ื”ืงืœืืกื™ืช, ื™ืฉื ื” ื’ื™ืฉื” ื—ืœื•ืคื™ืช ื”ืกืคืฆื™ืคื™ืช ืœืžืขืจื›ืช ื”ื”ืคืขืœื” macOS ื•ืื™ื ื” ื ืžืฆืืช ื‘-BSD. ืขืงืจื•ื ื•ืช ื”ืคืขื•ืœื” ืฉืœ ืฉืชื™ ืฉื™ื—ื•ืช ื”ืžืขืจื›ืช ื“ื•ืžื•ืช ืืฃ ื”ืŸ. ื”ืŸ ืงืจื™ืื•ืช ื™ืฉื™ืจื•ืช ืœืคื•ื ืงืฆื™ื™ืช ื”ืงืจื ืœ psignal. ื›ืžื• ื›ืŸ, ืฉื™ืžื• ืœื‘ ืฉืœืคื ื™ ื”ืจื™ื’ืช ืชื”ืœื™ืš, ืžืชื‘ืฆืขืช ื‘ื“ื™ืงืช "cansignal" - ื”ืื ื”ืชื”ืœื™ืš ื™ื›ื•ืœ ืœืฉืœื•ื— ืื•ืช ืœืชื”ืœื™ืš ืื—ืจ; ื”ืžืขืจื›ืช ืื™ื ื” ืžืืคืฉืจืช ืœืฉื•ื ืืคืœื™ืงืฆื™ื” ืœื”ืจื•ื’ ืชื”ืœื™ื›ื™ ืžืขืจื›ืช, ืœืžืฉืœ.

static int
terminate_with_payload_internal(struct proc *cur_proc, int target_pid, uint32_t reason_namespace,
				uint64_t reason_code, user_addr_t payload, uint32_t payload_size,
				user_addr_t reason_string, uint64_t reason_flags)
{
...
	target_proc = proc_find(target_pid);
...
	if (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL)) {
		proc_rele(target_proc);
		return EPERM;
	}
...
	if (target_pid == cur_proc->p_pid) {
		/*
		 * psignal_thread_with_reason() will pend a SIGKILL on the specified thread or
		 * return if the thread and/or task are already terminating. Either way, the
		 * current thread won't return to userspace.
		 */
		psignal_thread_with_reason(target_proc, current_thread(), SIGKILL, signal_reason);
	} else {
		psignal_with_reason(target_proc, SIGKILL, signal_reason);
	}
...
}

ื”ืฉื™ืงื”

ื”ื“ืจืš ื”ืกื˜ื ื“ืจื˜ื™ืช ืœื™ืฆื•ืจ ื“ืžื•ื ื™ื ื‘ืขืช ื”ืคืขืœืช ื”ืžืขืจื›ืช ื•ืœืฉืœื•ื˜ ื‘ื—ื™ื™ื”ื ืžื•ืฉืงืช. ืฉื™ื ืœื‘ ืฉื”ืžืงื•ืจื•ืช ื”ื ืขื‘ื•ืจ ื”ื’ืจืกื” ื”ื™ืฉื ื” ืฉืœ launchctl ืขื“ macOS 10.10, ื“ื•ื’ืžืื•ืช ืงื•ื“ ืžืกื•ืคืงื•ืช ืœืžื˜ืจื•ืช ื”ืžื—ืฉื”. Launchctl ืžื•ื“ืจื ื™ ืฉื•ืœื— ืื•ืชื•ืช ืฉื™ื’ื•ืจ ื‘ืืžืฆืขื•ืช XPC, ืœื•ื’ื™ืงืช launchctl ื”ื•ืขื‘ืจื” ืืœื™ื•.

ื‘ื•ืื• ื ืกืชื›ืœ ืื™ืš ื‘ื“ื™ื•ืง ืขื•ืฆืจื™ื ื™ื™ืฉื•ืžื™ื. ืœืคื ื™ ืฉืœื™ื—ืช ื”ืื•ืช SIGTERM, ืžื ืกื™ื ืœืขืฆื•ืจ ืืช ื”ื™ื™ืฉื•ื ื‘ืืžืฆืขื•ืช ืงืจื™ืืช ื”ืžืขืจื›ืช "proc_terminate".

<launchctl src/core.c>
...
	error = proc_terminate(j->p, &sig);
	if (error) {
		job_log(j, LOG_ERR | LOG_CONSOLE, "Could not terminate job: %d: %s", error, strerror(error));
		job_log(j, LOG_NOTICE | LOG_CONSOLE, "Using fallback option to terminate job...");
		error = kill2(j->p, SIGTERM);
		if (error) {
			job_log(j, LOG_ERR, "Could not signal job: %d: %s", error, strerror(error));
		} 
...
<>

ืžืชื—ืช ืœืžื›ืกื” ื”ืžื ื•ืข, proc_terminate, ืœืžืจื•ืช ืฉืžื•, ื™ื›ื•ืœ ืœืฉืœื•ื— ืœื ืจืง psignal ืขื SIGTERM, ืืœื ื’ื SIGKILL.

ื”ืจื’ ืขืงื™ืฃ - ืžื’ื‘ืœืช ืžืฉืื‘ื™ื

ืžืงืจื” ืžืขื ื™ื™ืŸ ื™ื•ืชืจ ื ื™ืชืŸ ืœืจืื•ืช ื‘ืฉื™ื—ืช ืžืขืจื›ืช ืื—ืจืช process_policy. ืฉื™ืžื•ืฉ ื ืคื•ืฅ ื‘ืงืจื™ืื” ืœืžืขืจื›ืช ื–ื• ื”ื•ื ืœื”ื’ื‘ื™ืœ ืžืฉืื‘ื™ ื™ื™ืฉื•ืžื™ื, ื›ื’ื•ืŸ ืื™ื ื“ืงืก ื›ื“ื™ ืœื”ื’ื‘ื™ืœ ืืช ื–ืžืŸ ื”-CPU ื•ืžื›ืกื•ืช ื”ื–ื™ื›ืจื•ืŸ ื›ืš ืฉื”ืžืขืจื›ืช ืœื ืชืื˜ ืžืฉืžืขื•ืชื™ืช ืขืœ ื™ื“ื™ ืคืขื™ืœื•ื™ื•ืช ืื—ืกื•ืŸ ืงื‘ืฆื™ื ื‘ืžื˜ืžื•ืŸ. ืื ื™ื™ืฉื•ื ื”ื’ื™ืข ืœืžื’ื‘ืœืช ื”ืžืฉืื‘ื™ื ืฉืœื•, ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช ืžื”ืคื•ื ืงืฆื™ื” proc_apply_resource_actions, ืื•ืช SIGKILL ื ืฉืœื— ืœืชื”ืœื™ืš.

ืœืžืจื•ืช ืฉืงืจื™ืืช ืžืขืจื›ืช ื–ื• ืขืœื•ืœื” ืœื”ืจื•ื’ ืชื”ืœื™ืš, ื”ืžืขืจื›ืช ืœื ื‘ื“ืงื” ื›ืจืื•ื™ ืืช ื”ื–ื›ื•ื™ื•ืช ืฉืœ ื”ืชื”ืœื™ืš ื”ืงื•ืจื ืœืงืจื™ืืช ื”ืžืขืจื›ืช. ื‘ืขืฆื ื‘ื•ื“ืง ื”ื™ื” ืงื™ื™ื, ืื‘ืœ ื“ื™ ืœื”ืฉืชืžืฉ ื‘ื“ื’ืœ ื”ื—ืœื•ืคื™ PROC_POLICY_ACTION_SET ื›ื“ื™ ืœืขืงื•ืฃ ืืช ื”ืชื ืื™ ื”ื–ื”.

ืœืคื™ื›ืš, ืื ืืชื” "ืžื’ื‘ื™ืœ" ืืช ืžื›ืกืช ื”ืฉื™ืžื•ืฉ ื‘-CPU ืฉืœ ื”ืืคืœื™ืงืฆื™ื” (ืœื“ื•ื’ืžื”, ืžืืคืฉืจ ืจืง 1 ns ืœืคืขื•ืœ), ืื– ืืชื” ื™ื›ื•ืœ ืœื”ืจื•ื’ ื›ืœ ืชื”ืœื™ืš ื‘ืžืขืจื›ืช. ืœืคื™ื›ืš, ื”ืชื•ื›ื ื” ื”ื–ื“ื•ื ื™ืช ื™ื›ื•ืœื” ืœื”ืจื•ื’ ื›ืœ ืชื”ืœื™ืš ื‘ืžืขืจื›ืช, ื›ื•ืœืœ ืชื”ืœื™ืš ื”ืื ื˜ื™ ื•ื™ืจื•ืก. ืžืขื ื™ื™ืŸ ื’ื ื”ื”ืฉืคืขื” ืฉืžืชืจื—ืฉืช ื›ืืฉืจ ื”ื•ืจื’ื™ื ืชื”ืœื™ืš ืขื pid 1 (launchctl) - ืคืื ื™ืงื” ืฉืœ ืงืจื ืœ ื›ืืฉืจ ืžื ืกื™ื ืœืขื‘ื“ ืืช ื”ืื•ืช SIGKILL :)

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ื›ื™ืฆื“ ื ื™ืชืŸ ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื”?

ื”ื“ืจืš ื”ืคืฉื•ื˜ื” ื‘ื™ื•ืชืจ ืœืžื ื•ืข ืชื”ืœื™ืš ืžืœื”ื™ื•ืช ื”ื™ื ืœื”ื—ืœื™ืฃ ืืช ืžืฆื‘ื™ืข ื”ืคื•ื ืงืฆื™ื•ืช ื‘ื˜ื‘ืœืช ื”ืงืจื™ืื•ืช ืฉืœ ื”ืžืขืจื›ืช. ืœืžืจื‘ื” ื”ืฆืขืจ, ืฉื™ื˜ื” ื–ื• ืื™ื ื” ื˜ืจื™ื•ื•ื™ืืœื™ืช ืžืกื™ื‘ื•ืช ืจื‘ื•ืช.

ืจืืฉื™ืช, ื”ืกืžืœ ื”ืฉื•ืœื˜ ื‘ืžื™ืงื•ื ื”ื–ื™ื›ืจื•ืŸ ืฉืœ sysent ืื™ื ื• ืคืจื˜ื™ ืจืง ืœืกืžืœ ื”ืœื™ื‘ื” ืฉืœ XNU, ืืœื ืœื ื ื™ืชืŸ ืœืžืฆื•ื ืื•ืชื• ื‘ืกืžืœื™ ื”ืœื™ื‘ื”. ืชืฆื˜ืจืš ืœื”ืฉืชืžืฉ ื‘ืฉื™ื˜ื•ืช ื—ื™ืคื•ืฉ ื”ื™ื•ืจื™ืกื˜ื™ื•ืช, ื›ืžื• ืคื™ืจื•ืง ื“ื™ื ืžื™ ืฉืœ ื”ืคื•ื ืงืฆื™ื” ื•ื—ื™ืคื•ืฉ ืžืฆื‘ื™ืข ื‘ื”.

ืฉื ื™ืช, ืžื‘ื ื” ื”ืขืจื›ื™ื ื‘ื˜ื‘ืœื” ืชืœื•ื™ ื‘ื“ื’ืœื™ื ืฉืื™ืชื ื”ื™ื“ื•ืจ ื”ืงืจื ืœ. ืื ื”ื•ื›ืจื– ื”ื“ื’ืœ CONFIG_REQUIRES_U32_MUNGING, ื’ื•ื“ืœ ื”ืžื‘ื ื” ื™ืฉืชื ื” - ื™ืชื•ื•ืกืฃ ืฉื“ื” ื ื•ืกืฃ sy_arg_munge32. ื™ืฉ ืฆื•ืจืš ืœื‘ืฆืข ื‘ื“ื™ืงื” ื ื•ืกืคืช ื›ื“ื™ ืœืงื‘ื•ืข ื‘ืื™ื–ื” ื“ื’ืœ ื”ืœื™ื‘ื” ื”ื™ื“ื•ืจ, ืื• ืœื—ื™ืœื•ืคื™ืŸ, ืœื‘ื“ื•ืง ืžืฆื‘ื™ืขื™ ืคื•ื ืงืฆื™ื•ืช ืžื•ืœ ื™ื“ื•ืขื™ื.

struct sysent {         /* system call table */
        sy_call_t       *sy_call;       /* implementing function */
#if CONFIG_REQUIRES_U32_MUNGING || (__arm__ && (__BIGGEST_ALIGNMENT__ > 4))
        sy_munge_t      *sy_arg_munge32; /* system call arguments munger for 32-bit process */
#endif
        int32_t         sy_return_type; /* system call return types */
        int16_t         sy_narg;        /* number of args */
        uint16_t        sy_arg_bytes;   /* Total size of arguments in bytes for
                                         * 32-bit system calls
                                         */
};

ืœืžืจื‘ื” ื”ืžื–ืœ, ื‘ื’ืจืกืื•ืช ืžื•ื“ืจื ื™ื•ืช ืฉืœ macOS, ืืคืœ ืžืกืคืงืช API ื—ื“ืฉ ืœืขื‘ื•ื“ื” ืขื ืชื”ืœื™ื›ื™ื. ื”-API ืฉืœ Endpoint Security ืžืืคืฉืจ ืœืœืงื•ื—ื•ืช ืœืืฉืจ ื‘ืงืฉื•ืช ืจื‘ื•ืช ืœืชื”ืœื™ื›ื™ื ืื—ืจื™ื. ืœืคื™ื›ืš, ืืชื” ื™ื›ื•ืœ ืœื—ืกื•ื ื›ืœ ืื•ืชื•ืช ืœืชื”ืœื™ื›ื™ื, ื›ื•ืœืœ ืื•ืช SIGKILL, ื‘ืืžืฆืขื•ืช ื”-API ื”ื "ืœ.

#include <bsm/libbsm.h>
#include <EndpointSecurity/EndpointSecurity.h>
#include <unistd.h>

int main(int argc, const char * argv[]) {
    es_client_t* cli = nullptr;
    {
        auto res = es_new_client(&cli, ^(es_client_t * client, const es_message_t * message) {
            switch (message->event_type) {
                case ES_EVENT_TYPE_AUTH_SIGNAL:
                {
                    auto& msg = message->event.signal;
                    auto target = msg.target;
                    auto& token = target->audit_token;
                    auto pid = audit_token_to_pid(token);
                    printf("signal '%d' sent to pid '%d'n", msg.sig, pid);
                    es_respond_auth_result(client, message, pid == getpid() ? ES_AUTH_RESULT_DENY : ES_AUTH_RESULT_ALLOW, false);
                }
                    break;
                default:
                    break;
            }
        });
    }

    {
        es_event_type_t evs[] = { ES_EVENT_TYPE_AUTH_SIGNAL };
        es_subscribe(cli, evs, sizeof(evs) / sizeof(*evs));
    }

    printf("%dn", getpid());
    sleep(60); // could be replaced with other waiting primitive

    es_unsubscribe_all(cli);
    es_delete_client(cli);

    return 0;
}

ื‘ืื•ืคืŸ ื“ื•ืžื”, ื ื™ืชืŸ ืœืจืฉื•ื ืžื“ื™ื ื™ื•ืช MAC ื‘ืœื™ื‘ื”, ื”ืžืกืคืงืช ืฉื™ื˜ืช ื”ื’ื ื” ืขืœ ืื•ืชื•ืช (policy proc_check_signal), ืืš ื”-API ืื™ื ื• ื ืชืžืš ืจืฉืžื™ืช.

ื”ื’ื ื” ืขืœ ื”ืจื—ื‘ืช ืœื™ื‘ื”

ื‘ื ื•ืกืฃ ืœื”ื’ื ื” ืขืœ ืชื”ืœื™ื›ื™ื ื‘ืžืขืจื›ืช, ื™ืฉ ืฆื•ืจืš ื’ื ื‘ื”ื’ื ื” ืขืœ ืชื•ืกืฃ ื”ืงืจื ืœ ืขืฆืžื• (kext). macOS ืžืกืคืงืช ืžืกื’ืจืช ืœืžืคืชื—ื™ื ืœืคืชื— ื‘ืงืœื•ืช ืžื ื”ืœื™ ื”ืชืงื ื™ื ืฉืœ IOKit. ื‘ื ื•ืกืฃ ืœืืกืคืงืช ื›ืœื™ื ืœืขื‘ื•ื“ื” ืขื ืžื›ืฉื™ืจื™ื, IOKit ืžืกืคืงืช ืฉื™ื˜ื•ืช ืœืขืจื™ืžืช ืžื ื”ืœื™ ื”ืชืงื ื™ื ื‘ืืžืฆืขื•ืช ืžื•ืคืขื™ื ืฉืœ ืžื—ืœืงื•ืช C++. ืืคืœื™ืงืฆื™ื” ื‘ืžืจื—ื‘ ื”ืžืฉืชืžืฉ ืชื•ื›ืœ "ืœืžืฆื•ื" ืžื•ืคืข ืจืฉื•ื ืฉืœ ื”ืžื—ืœืงื” ื›ื“ื™ ืœื™ืฆื•ืจ ืงืฉืจ ืœื™ื‘ื”-userspace.

ื›ื“ื™ ืœื–ื”ื•ืช ืืช ืžืกืคืจ ืžื•ืคืขื™ ื”ืžื—ืœืงื” ื‘ืžืขืจื›ืช, ื™ืฉ ืืช ื›ืœื™ ื”ืฉื™ืจื•ืช ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

ื›ืœ ืกื™ื•ืžืช ืœื™ื‘ื” ืฉืจื•ืฆื” ืœื”ื™ืจืฉื ื‘ืขืจื™ืžืช ื”ื“ืจื™ื™ื‘ืจ ื—ื™ื™ื‘ืช ืœื”ื›ืจื™ื– ืขืœ ืžื—ืœืงื” ืฉื™ื•ืจืฉืช ืž-IOService, ืœืžืฉืœ my_kext_ioservice ื‘ืžืงืจื” ื–ื”. ื—ื™ื‘ื•ืจ ื™ื™ืฉื•ืžื™ ืžืฉืชืžืฉ ื’ื•ืจื ืœื™ืฆื™ืจืช ืžื•ืคืข ื—ื“ืฉ ืฉืœ ื”ืžื—ืœืงื” ืฉื™ื•ืจืฉืช ืž-IOUserClient, ื‘ื“ื•ื’ืžื” my_kext_iouserclient.

ื›ืืฉืจ ืžื ืกื™ื ืœืคืจื•ืง ืžื ื”ืœ ื”ืชืงืŸ ืžื”ืžืขืจื›ืช (ืคืงื•ื“ื” kextunload), ื”ืคื•ื ืงืฆื™ื” ื”ื•ื™ืจื˜ื•ืืœื™ืช "bool terminate (IOOptionBits options)" ื ืงืจืืช. ื–ื” ืžืกืคื™ืง ื›ื“ื™ ืœื”ื—ื–ื™ืจ false ืขืœ ื”ืฉื™ื—ื” ื›ื“ื™ ืœืกื™ื™ื ื›ืืฉืจ ืžื ืกื™ื ืœืคืจื•ืง ื›ื“ื™ ืœื”ืฉื‘ื™ืช kextunload.

bool Kext::terminate(IOOptionBits options)
{

  if (!IsUnloadAllowed)
  {
    // Unload is not allowed, returning false
    return false;
  }

  return super::terminate(options);
}

ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช ื”ื“ื’ืœ IsUnloadAllowed ืขืœ ื™ื“ื™ IOUserClient ื‘ืขืช ื”ื˜ืขื™ื ื”. ื›ืืฉืจ ื™ืฉ ืžื’ื‘ืœืช ื”ื•ืจื“ื”, ื”ืคืงื•ื“ื” kextunload ืชื—ื–ื™ืจ ืืช ื”ืคืœื˜ ื”ื‘ื:

admin@admins-Mac drivermanager % sudo kextunload ./test.kext
Password:
(kernel) Can't remove kext my.kext.test; services failed to terminate - 0xe00002c7.
Failed to unload my.kext.test - (iokit/common) unsupported function.

ื”ื’ื ื” ื“ื•ืžื” ื—ื™ื™ื‘ืช ืœื”ื™ืขืฉื•ืช ืขื‘ื•ืจ IOUserClient. ื ื™ืชืŸ ืœื”ืกื™ืจ ืžื•ืคืขื™ื ืฉืœ ืžื—ืœืงื•ืช ื‘ืืžืฆืขื•ืช ืคื•ื ืงืฆื™ื™ืช ืžืจื—ื‘ ื”ืžืฉืชืžืฉ ืฉืœ IOKitLib "IOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);". ืืชื” ื™ื›ื•ืœ ืœื”ื—ื–ื™ืจ false ื‘ืขืช ืงืจื™ืื” ืœืคืงื•ื“ื” "terminate" ืขื“ ืฉื™ื™ืฉื•ื ืžืจื—ื‘ ื”ืžืฉืชืžืฉ "ืžืช", ื›ืœื•ืžืจ, ื”ืคื•ื ืงืฆื™ื” "clientDied" ืœื ืชื™ืงืจื.

ื”ื’ื ื” ืขืœ ืงื‘ืฆื™ื

ื›ื“ื™ ืœื”ื’ืŸ ืขืœ ืงื‘ืฆื™ื, ืžืกืคื™ืง ืœื”ืฉืชืžืฉ ื‘-Kauth API, ื”ืžืืคืฉืจ ืœื”ื’ื‘ื™ืœ ืืช ื”ื’ื™ืฉื” ืœืงื‘ืฆื™ื. ืืคืœ ืžืกืคืงืช ืœืžืคืชื—ื™ื ื”ื•ื“ืขื•ืช ืขืœ ืื™ืจื•ืขื™ื ืฉื•ื ื™ื ื‘ื”ื™ืงืฃ; ืขื‘ื•ืจื ื•, ื”ืคืขื•ืœื•ืช KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA ื•-KAUTH_VNODE_DELETE_CHILD ื—ืฉื•ื‘ื•ืช. ื”ื“ืจืš ื”ืงืœื” ื‘ื™ื•ืชืจ ืœื”ื’ื‘ื™ืœ ืืช ื”ื’ื™ืฉื” ืœืงื‘ืฆื™ื ื”ื™ื ื‘ืืžืฆืขื•ืช ื ืชื™ื‘ - ืื ื• ืžืฉืชืžืฉื™ื ื‘-API "vn_getpath" ื›ื“ื™ ืœืงื‘ืœ ืืช ื”ื ืชื™ื‘ ืœืงื•ื‘ืฅ ื•ืœื”ืฉื•ื•ืช ืืช ืงื™ื“ื•ืžืช ื”ื ืชื™ื‘. ืฉื™ืžื• ืœื‘ ืฉื›ื“ื™ ืœื™ื™ืขืœ ืืช ืฉืžื•ืช ื”ื ืชื™ื‘ื™ื ืฉืœ ืชื™ืงื™ื•ืช ื”ืงื‘ืฆื™ื, ื”ืžืขืจื›ืช ืœื ืžืืฉืจืช ื’ื™ืฉื” ืœื›ืœ ืงื•ื‘ืฅ, ืืœื ืจืง ืœืชื™ืงื™ื” ืขืฆืžื” ืฉืฉืžื” ืฉื•ื ื”. ื™ืฉ ืฆื•ืจืš ืœื”ืฉื•ื•ืช ืืช ื ืชื™ื‘ ื”ืื‘ ื•ืœื”ื’ื‘ื™ืœ ืืช KAUTH_VNODE_DELETE ืขื‘ื•ืจื•.

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ื”ื—ื™ืกืจื•ืŸ ืฉืœ ื’ื™ืฉื” ื–ื• ืขืฉื•ื™ ืœื”ื™ื•ืช ื‘ื™ืฆื•ืขื™ื ื ืžื•ื›ื™ื ื›ื›ืœ ืฉืžืกืคืจ ื”ืงื™ื“ื•ืžื•ืช ื’ื“ืœ. ื›ื“ื™ ืœื”ื‘ื˜ื™ื— ืฉื”ื”ืฉื•ื•ืื” ืœื ืชื”ื™ื” ืฉื•ื•ื” ืœ-O(ืงื™ื“ื•ืžืช*ืื•ืจืš), ื›ืืฉืจ ืงื™ื“ื•ืžืช ื”ื™ื ืžืกืคืจ ื”ืงื™ื“ื•ืžื•ืช, ืื•ืจืš ื”ื•ื ืื•ืจืš ื”ืžื—ืจื•ื–ืช, ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืื•ื˜ื•ืžื˜ ืกื•ืคื™ ื“ื˜ืจืžื™ื ื™ืกื˜ื™ (DFA) ืฉื ื‘ื ื” ืขืœ ื™ื“ื™ ืงื™ื“ื•ืžื•ืช.

ื”ื‘ื” ื ืฉืงื•ืœ ืฉื™ื˜ื” ืœื‘ื ื™ื™ืช DFA ืขื‘ื•ืจ ืงื‘ื•ืฆื” ื ืชื•ื ื” ืฉืœ ืงื™ื“ื•ืžื•ืช. ืื ื• ืžืืชื—ืœื™ื ืืช ื”ืกืžื ื™ื ื‘ืชื—ื™ืœืช ื›ืœ ืงื™ื“ื•ืžืช. ืื ื›ืœ ื”ืกืžื ื™ื ืžืฆื‘ื™ืขื™ื ืขืœ ืื•ืชื• ืชื•, ื”ื’ื“ืœ ื›ืœ ืกืžืŸ ื‘ืชื• ืื—ื“ ื•ื–ื›ื•ืจ ืฉืื•ืจืš ืื•ืชื” ืฉื•ืจื” ื’ื“ื•ืœ ื™ื•ืชืจ ื‘ืื—ื“. ืื ื™ืฉ ืฉื ื™ ืกืžื ื™ื ืขื ืกืžืœื™ื ืฉื•ื ื™ื, ื—ืœืงื• ืืช ื”ืกืžื ื™ื ืœืงื‘ื•ืฆื•ืช ืœืคื™ ื”ืกืžืœ ืฉื”ื ืžืฆื‘ื™ืขื™ื ืขืœื™ื• ื•ื—ื–ืจื• ืขืœ ื”ืืœื’ื•ืจื™ืชื ืขื‘ื•ืจ ื›ืœ ืงื‘ื•ืฆื”.

ื‘ืžืงืจื” ื”ืจืืฉื•ืŸ (ื›ืœ ื”ืชื•ื•ื™ื ืžืชื—ืช ืœืกืžื ื™ื ื–ื”ื™ื), ื ืงื‘ืœ ืžืฆื‘ DFA ืฉื™ืฉ ืœื• ืจืง ืžืขื‘ืจ ืื—ื“ ื‘ืื•ืชื• ืงื•. ื‘ืžืงืจื” ื”ืฉื ื™, ื ืงื‘ืœ ื˜ื‘ืœืช ืžืขื‘ืจื™ื ื‘ื’ื•ื“ืœ 256 (ืžืกืคืจ ืชื•ื•ื™ื ื•ืžืกืคืจ ืžืงืกื™ืžืœื™ ืฉืœ ืงื‘ื•ืฆื•ืช) ืœืžืฆื‘ื™ื ื”ื‘ืื™ื ื”ืžืชืงื‘ืœื™ื ืขืœ ื™ื“ื™ ืงืจื™ืื” ืจืงื•ืจืกื™ื‘ื™ืช ืœืคื•ื ืงืฆื™ื”.

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื”. ืขื‘ื•ืจ ืงื‘ื•ืฆื” ืฉืœ ืงื™ื“ื•ืžื•ืช ("/foo/bar/tmp/", "/var/db/foo/", "/foo/bar/aba/", "foo/bar/aac/"), ืืชื” ื™ื›ื•ืœ ืœืงื‘ืœ ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื DFA. ื”ืื™ื•ืจ ืžืฆื™ื’ ืจืง ืžืขื‘ืจื™ื ื”ืžื•ื‘ื™ืœื™ื ืœืžื“ื™ื ื•ืช ืื—ืจื•ืช; ืžืขื‘ืจื™ื ืื—ืจื™ื ืœื ื™ื”ื™ื• ืกื•ืคื™ื™ื.

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ื›ืืฉืจ ืขื•ื‘ืจื™ื ืขืœ ืžืฆื‘ื™ DKA, ืขืฉื•ื™ื™ื ืœื”ื™ื•ืช 3 ืžืงืจื™ื.

  1. ื”ืžืฆื‘ ื”ืกื•ืคื™ ื”ื’ื™ืข - ื”ื ืชื™ื‘ ืžื•ื’ืŸ, ืื ื• ืžื’ื‘ื™ืœื™ื ืืช ื”ืคืขื•ืœื•ืช KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA ื•-KAUTH_VNODE_DELETE_CHILD
  2. ื”ืžืฆื‘ ื”ืกื•ืคื™ ืœื ื”ื•ืฉื’, ืื‘ืœ ื”ื ืชื™ื‘ "ื”ืกืชื™ื™ื" (ื”ื’ื™ืข ืœ-null terminator) - ื”ื ืชื™ื‘ ื”ื•ื ืื‘, ื™ืฉ ืฆื•ืจืš ืœื”ื’ื‘ื™ืœ ืืช KAUTH_VNODE_DELETE. ืฉื™ืžื• ืœื‘ ืฉืื vnode ื”ื™ื ืชื™ืงื™ื”, ืขืœื™ื›ื ืœื”ื•ืกื™ืฃ '/' ื‘ืกื•ืฃ, ืื—ืจืช ื–ื” ืขืœื•ืœ ืœื”ื’ื‘ื™ืœ ืื•ืชื• ืœืงื•ื‘ืฅ "/foor/bar/t", ืฉื”ื•ื ืฉื’ื•ื™.
  3. ื”ืžืฆื‘ ื”ืกื•ืคื™ ืœื ื”ื•ืฉื’, ื”ื“ืจืš ืœื ื”ืกืชื™ื™ืžื”. ืืฃ ืื—ืช ืžื”ืงื™ื“ื•ืžื•ืช ืœื ืชื•ืืžืช ืืช ื–ื”, ืื ื—ื ื• ืœื ืžืฆื™ื’ื™ื ื”ื’ื‘ืœื•ืช.

ืžืกืงื ื”

ืžื˜ืจืช ืคืชืจื•ื ื•ืช ื”ืื‘ื˜ื—ื” ื”ืžืคื•ืชื—ื™ื ื”ื™ื ืœื”ื’ื‘ื™ืจ ืืช ืจืžืช ื”ืื‘ื˜ื—ื” ืฉืœ ื”ืžืฉืชืžืฉ ื•ื”ื ืชื•ื ื™ื ืฉืœื•. ืžืฆื“ ืื—ื“, ืžื˜ืจื” ื–ื• ืžื•ืฉื’ืช ืขืœ ื™ื“ื™ ืคื™ืชื•ื— ืžื•ืฆืจ ื”ืชื•ื›ื ื” Acronis, ืฉืกื•ื’ืจ ืืช ืื•ืชืŸ ื ืงื•ื“ื•ืช ืชื•ืจืคื” ืฉื‘ื”ืŸ ืžืขืจื›ืช ื”ื”ืคืขืœื” ืขืฆืžื” "ื—ืœืฉื”". ืžืฆื“ ืฉื ื™, ืืœ ืœื ื• ืœื”ื–ื ื™ื— ืืช ื—ื™ื–ื•ืง ื”ื™ื‘ื˜ื™ ื”ืื‘ื˜ื—ื” ื”ื ื™ืชื ื™ื ืœืฉื™ืคื•ืจ ื‘ืฆื“ ืžืขืจื›ืช ื”ื”ืคืขืœื”, ื‘ืžื™ื•ื—ื“ ืžืื—ืจ ืฉืกื’ื™ืจืช ื ืงื•ื“ื•ืช ืชื•ืจืคื” ื›ืืœื” ืžื’ื‘ื™ืจื” ืืช ื”ื™ืฆื™ื‘ื•ืช ืฉืœื ื• ื›ืžื•ืฆืจ. ื”ืคื’ื™ืขื•ืช ื“ื•ื•ื—ื” ืœืฆื•ื•ืช ืื‘ื˜ื—ืช ื”ืžื•ืฆืจ ืฉืœ Apple ื•ื”ื™ื ืชื•ืงื ื” ื‘-macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ืชื”ืœื™ื›ื™ื ื•ื”ืจื—ื‘ื•ืช ืœื™ื‘ื” ื‘-macOS

ื›ืœ ื–ื” ื™ื›ื•ืœ ืœื”ื™ืขืฉื•ืช ืจืง ืื ื›ืœื™ ื”ืฉื™ืจื•ืช ืฉืœืš ื”ื•ืชืงืŸ ืจืฉืžื™ืช ื‘ืœื™ื‘ื”. ื›ืœื•ืžืจ, ืื™ืŸ ืคืจืฆื•ืช ื›ืืœื” ืœืชื•ื›ื ื•ืช ื—ื™ืฆื•ื ื™ื•ืช ื•ืœื ืจืฆื•ื™ื•ืช. ืขื ื–ืืช, ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช, ืืคื™ืœื• ื”ื’ื ื” ืขืœ ืชื•ื›ื ื•ืช ืœื’ื™ื˜ื™ืžื™ื•ืช ื›ื’ื•ืŸ ืื ื˜ื™ ื•ื™ืจื•ืก ื•ืžืขืจื›ื•ืช ื’ื™ื‘ื•ื™ ื“ื•ืจืฉืช ืขื‘ื•ื“ื”. ืืš ื›ืขืช ืœืžื•ืฆืจื™ Acronis ื”ื—ื“ืฉื™ื ืขื‘ื•ืจ macOS ืชื”ื™ื” ื”ื’ื ื” ื ื•ืกืคืช ืžืคื ื™ ืคืจื™ืงื” ืžื”ืžืขืจื›ืช.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”