ืฉืืื, ืืืจ! ืืืื ืื ื ืจืืฆื ืืืืจ ืขื ืืื ืืชื ืืืื ืืืื ืขื ืชืืืืืื ืืคื ื ืืชืงืคืืช ืฉื ืชืืงืคืื ื-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 ืืื ืื ืื ืื ืืคื ืืืืื ืฉื ืืงืจื ื (ืื ืื ืื ืขืฉืืืื ืืืืืช ืื ืืจืืืืืืืืื, ืืื ื ืฉืืืจ ืืืชื ืืืืืจ ืืืจ ๐ - ืืืืืช ืืชืืื, ืฉืืืืืช ืืืืจืื, ืืืคืื ืืืฆืืื/ืกืืื, ืืคืจืืช ืฉื ืืื ื ืขื ืงืืฆืื, ืืื '
ื ืชืืื ืืช ืืกืงืืจื ืขื ืืคืื ืงืฆืื ืืงืจืืืช ืืืขืจืืช ืืืชืืืื
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.
ืืจื ืขืงืืฃ - ืืืืืช ืืฉืืืื
ืืงืจื ืืขื ืืื ืืืชืจ ื ืืชื ืืจืืืช ืืฉืืืช ืืขืจืืช ืืืจืช
ืืืจืืช ืฉืงืจืืืช ืืขืจืืช ืื ืขืืืื ืืืจืื ืชืืืื, ืืืขืจืืช ืื ืืืงื ืืจืืื ืืช ืืืืืืืช ืฉื ืืชืืืื ืืงืืจื ืืงืจืืืช ืืืขืจืืช. ืืขืฆื ืืืืง
ืืคืืื, ืื ืืชื "ืืืืื" ืืช ืืืกืช ืืฉืืืืฉ ื-CPU ืฉื ืืืคืืืงืฆืื (ืืืืืื, ืืืคืฉืจ ืจืง 1 ns ืืคืขืื), ืื ืืชื ืืืื ืืืจืื ืื ืชืืืื ืืืขืจืืช. ืืคืืื, ืืชืืื ื ืืืืื ืืช ืืืืื ืืืจืื ืื ืชืืืื ืืืขืจืืช, ืืืื ืชืืืื ืืื ืื ืืืจืืก. ืืขื ืืื ืื ืืืฉืคืขื ืฉืืชืจืืฉืช ืืืฉืจ ืืืจืืื ืชืืืื ืขื pid 1 (launchctl) - ืคืื ืืงื ืฉื ืงืจื ื ืืืฉืจ ืื ืกืื ืืขืื ืืช ืืืืช SIGKILL :)
ืืืฆื ื ืืชื ืืคืชืืจ ืืช ืืืขืื?
ืืืจื ืืคืฉืืื ืืืืชืจ ืืื ืืข ืชืืืื ืืืืืืช ืืื ืืืืืืฃ ืืช ืืฆืืืข ืืคืื ืงืฆืืืช ืืืืืช ืืงืจืืืืช ืฉื ืืืขืจืืช. ืืืจืื ืืฆืขืจ, ืฉืืื ืื ืืื ื ืืจืืืืืืืืช ืืกืืืืช ืจืืืช.
ืจืืฉืืช, ืืกืื ืืฉืืื ืืืืงืื ืืืืืจืื ืฉื sysent ืืื ื ืคืจืื ืจืง ืืกืื ืืืืื ืฉื XNU, ืืื ืื ื ืืชื ืืืฆืื ืืืชื ืืกืืื ืืืืื. ืชืฆืืจื ืืืฉืชืืฉ ืืฉืืืืช ืืืคืืฉ ืืืืจืืกืืืืช, ืืื ืคืืจืืง ืืื ืื ืฉื ืืคืื ืงืฆืื ืืืืคืืฉ ืืฆืืืข ืื.
ืฉื ืืช, ืืื ื ืืขืจืืื ืืืืื ืชืืื ืืืืืื ืฉืืืชื ืืืืืจ ืืงืจื ื. ืื ืืืืจื ืืืื CONFIG_REQUIRES_U32_MUNGING, ืืืื ืืืื ื ืืฉืชื ื - ืืชืืืกืฃ ืฉืื ื ืืกืฃ
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 ืขืืืจื.
ืืืืกืจืื ืฉื ืืืฉื ืื ืขืฉืื ืืืืืช ืืืฆืืขืื ื ืืืืื ืืื ืฉืืกืคืจ ืืงืืืืืืช ืืื. ืืื ืืืืืื ืฉืืืฉืืืื ืื ืชืืื ืฉืืื ื-O(ืงืืืืืช*ืืืจื), ืืืฉืจ ืงืืืืืช ืืื ืืกืคืจ ืืงืืืืืืช, ืืืจื ืืื ืืืจื ืืืืจืืืช, ื ืืชื ืืืฉืชืืฉ ืืืืืืื ืกืืคื ืืืจืืื ืืกืื (DFA) ืฉื ืื ื ืขื ืืื ืงืืืืืืช.
ืืื ื ืฉืงืื ืฉืืื ืืื ืืืช DFA ืขืืืจ ืงืืืฆื ื ืชืื ื ืฉื ืงืืืืืืช. ืื ื ืืืชืืืื ืืช ืืกืื ืื ืืชืืืืช ืื ืงืืืืืช. ืื ืื ืืกืื ืื ืืฆืืืขืื ืขื ืืืชื ืชื, ืืืื ืื ืกืื ืืชื ืืื ืืืืืจ ืฉืืืจื ืืืชื ืฉืืจื ืืืื ืืืชืจ ืืืื. ืื ืืฉ ืฉื ื ืกืื ืื ืขื ืกืืืื ืฉืื ืื, ืืืงื ืืช ืืกืื ืื ืืงืืืฆืืช ืืคื ืืกืื ืฉืื ืืฆืืืขืื ืขืืื ืืืืจื ืขื ืืืืืืจืืชื ืขืืืจ ืื ืงืืืฆื.
ืืืงืจื ืืจืืฉืื (ืื ืืชืืืื ืืชืืช ืืกืื ืื ืืืื), ื ืงืื ืืฆื DFA ืฉืืฉ ืื ืจืง ืืขืืจ ืืื ืืืืชื ืงื. ืืืงืจื ืืฉื ื, ื ืงืื ืืืืช ืืขืืจืื ืืืืื 256 (ืืกืคืจ ืชืืืื ืืืกืคืจ ืืงืกืืืื ืฉื ืงืืืฆืืช) ืืืฆืืื ืืืืื ืืืชืงืืืื ืขื ืืื ืงืจืืื ืจืงืืจืกืืืืช ืืคืื ืงืฆืื.
ืืืื ื ืกืชืื ืขื ืืืืื. ืขืืืจ ืงืืืฆื ืฉื ืงืืืืืืช ("/foo/bar/tmp/", "/var/db/foo/", "/foo/bar/aba/", "foo/bar/aac/"), ืืชื ืืืื ืืงืื ืืช ืืืืจืื ืืืืื DFA. ืืืืืจ ืืฆืื ืจืง ืืขืืจืื ืืืืืืืื ืืืืื ืืช ืืืจืืช; ืืขืืจืื ืืืจืื ืื ืืืื ืกืืคืืื.
ืืืฉืจ ืขืืืจืื ืขื ืืฆืื DKA, ืขืฉืืืื ืืืืืช 3 ืืงืจืื.
- ืืืฆื ืืกืืคื ืืืืข - ืื ืชืื ืืืื, ืื ื ืืืืืืื ืืช ืืคืขืืืืช KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA ื-KAUTH_VNODE_DELETE_CHILD
- ืืืฆื ืืกืืคื ืื ืืืฉื, ืืื ืื ืชืื "ืืกืชืืื" (ืืืืข ื-null terminator) - ืื ืชืื ืืื ืื, ืืฉ ืฆืืจื ืืืืืื ืืช KAUTH_VNODE_DELETE. ืฉืืื ืื ืฉืื vnode ืืื ืชืืงืื, ืขืืืื ืืืืกืืฃ '/' ืืกืืฃ, ืืืจืช ืื ืขืืื ืืืืืื ืืืชื ืืงืืืฅ "/foor/bar/t", ืฉืืื ืฉืืื.
- ืืืฆื ืืกืืคื ืื ืืืฉื, ืืืจื ืื ืืกืชืืืื. ืืฃ ืืืช ืืืงืืืืืืช ืื ืชืืืืช ืืช ืื, ืื ืื ื ืื ืืฆืืืื ืืืืืืช.
ืืกืงื ื
ืืืจืช ืคืชืจืื ืืช ืืืืืื ืืืคืืชืืื ืืื ืืืืืืจ ืืช ืจืืช ืืืืืื ืฉื ืืืฉืชืืฉ ืืื ืชืื ืื ืฉืื. ืืฆื ืืื, ืืืจื ืื ืืืฉืืช ืขื ืืื ืคืืชืื ืืืฆืจ ืืชืืื ื Acronis, ืฉืกืืืจ ืืช ืืืชื ื ืงืืืืช ืชืืจืคื ืฉืืื ืืขืจืืช ืืืคืขืื ืขืฆืื "ืืืฉื". ืืฆื ืฉื ื, ืื ืื ื ืืืื ืื ืืช ืืืืืง ืืืืื ืืืืืื ืื ืืชื ืื ืืฉืืคืืจ ืืฆื ืืขืจืืช ืืืคืขืื, ืืืืืื ืืืืจ ืฉืกืืืจืช ื ืงืืืืช ืชืืจืคื ืืืื ืืืืืจื ืืช ืืืฆืืืืช ืฉืื ื ืืืืฆืจ. ืืคืืืขืืช ืืืืื ืืฆืืืช ืืืืืช ืืืืฆืจ ืฉื Apple ืืืื ืชืืงื ื ื-macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).
ืื ืื ืืืื ืืืืขืฉืืช ืจืง ืื ืืื ืืฉืืจืืช ืฉืื ืืืชืงื ืจืฉืืืช ืืืืื. ืืืืืจ, ืืื ืคืจืฆืืช ืืืื ืืชืืื ืืช ืืืฆืื ืืืช ืืื ืจืฆืืืืช. ืขื ืืืช, ืืคื ืฉืืชื ืืืื ืืจืืืช, ืืคืืื ืืื ื ืขื ืชืืื ืืช ืืืืืืืืืช ืืืื ืื ืื ืืืจืืก ืืืขืจืืืช ืืืืื ืืืจืฉืช ืขืืืื. ืื ืืขืช ืืืืฆืจื Acronis ืืืืฉืื ืขืืืจ macOS ืชืืื ืืื ื ื ืืกืคืช ืืคื ื ืคืจืืงื ืืืืขืจืืช.
ืืงืืจ: www.habr.com