Aloha, Habr! I kēia lā makemake wau e kamaʻilio e pili ana i ke ʻano e hiki ai iā ʻoe ke pale i nā kaʻina mai ka hoʻouka ʻana e nā mea hoʻouka ma macOS. No ka laʻana, pono kēia no kahi antivirus a i ʻole ʻōnaehana backup, ʻoiai ma lalo o macOS aia nā ala he nui e "pepehi" i kahi kaʻina hana. E heluhelu e pili ana i kēia a me nā ʻano pale ma lalo o ka ʻoki.
ʻO ke ala maʻamau e "pepehi" i kahi kaʻina hana
ʻO kahi ala kaulana e "pepehi" i kahi kaʻina hana ʻo ka hoʻouna ʻana i kahi hōʻailona SIGKILL i ke kaʻina hana. Ma o ka bash hiki iā ʻoe ke kāhea i ka maʻamau "kill -SIGKILL PID" a i ʻole "pkill -9 NAME" e pepehi. Ua ʻike ʻia ke kauoha "pepehi" mai nā lā o UNIX a loaʻa ʻaʻole wale ma macOS, akā ma nā ʻōnaehana UNIX-like ʻē aʻe.
E like me nā ʻōnaehana UNIX-like, ʻae ʻo macOS iā ʻoe e hoʻopaʻa i nā hōʻailona i kahi kaʻina hana koe ʻelua - SIGKILL a me SIGSTOP. E kālele nui ana kēia ʻatikala i ka hōʻailona SIGKILL ma ke ʻano he hōʻailona e make ai ke kaʻina hana.
macOS kiko'ī
Ma ka macOS, kāhea ka ʻōnaehana pepehi i ka kernel XNU i ka hana psignal (SIGKILL,...). E ho'āʻo kākou e ʻike i nā hana mea hoʻohana ʻē aʻe i hiki ke kapa ʻia e ka hana psignal. E hoʻopau i nā kelepona i ka hana psignal i loko o nā mīkini o loko o ka kernel (ʻoiai he mea ʻole lākou, e waiho mākou iā lākou no kahi ʻatikala ʻē aʻe 🙂 - hōʻoia hōʻailona, hewa hoʻomanaʻo, puka / hoʻopau i ka lawelawe ʻana, nā hewa palekana file, etc. .
E hoʻomaka kākou i ka loiloi me ka hana a me ke kelepona ʻōnaehana pili
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);
}
...
}
hoʻokuʻu ʻia
Hoʻomaka ʻia ke ala maʻamau e hana ai i nā daemons i ka hoʻomaka ʻana o ka ʻōnaehana a mālama i ko lākou ola. E ʻoluʻolu e hoʻomaopopo ʻo nā kumu no ka mana kahiko o launchctl a hiki i ka macOS 10.10, hāʻawi ʻia nā code code no nā kumu hoʻohālike. Hoʻouna ʻo launchctl hou i nā hōʻailona hoʻolaha ma o XPC, ua hoʻoneʻe ʻia ka loiloi launchctl iā ia.
E nānā kākou i ka pau ʻana o nā noi. Ma mua o ka hoʻouna ʻana i ka hōʻailona SIGTERM, hoʻāʻo ʻia ka noi e hoʻōki me ka hoʻohana ʻana i ke kelepona ʻōnaehana "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));
}
...
<>
Ma lalo o ka hood, proc_terminate, ʻoiai kona inoa, hiki ke hoʻouna ʻaʻole wale i ka psignal me SIGTERM, akā ʻo SIGKILL pū kekahi.
Pepehi ʻole - Ka palena waiwai
Hiki ke ʻike ʻia kahi hihia hoihoi hou aʻe ma kahi kelepona ʻōnaehana
ʻOiai hiki i kēia kelepona pūnaewele ke pepehi i kahi kaʻina hana, ʻaʻole i nānā pono ka ʻōnaehana i nā kuleana o ke kaʻina e kāhea ana i ke kelepona ʻōnaehana. Ke nānā maoli nei
No laila, inā ʻoe e "palena" i ka quota hoʻohana CPU o ka noi (no ka laʻana, e ʻae wale i ka 1 ns e holo), a laila hiki iā ʻoe ke pepehi i kekahi kaʻina hana i ka ʻōnaehana. No laila, hiki i ka malware ke pepehi i kekahi kaʻina hana ma ka ʻōnaehana, me ke kaʻina antivirus. He mea hoihoi nō hoʻi ka hopena i ka wā e pepehi ai i kahi kaʻina hana me pid 1 (launchctl) - kernel panic i ka wā e hoʻāʻo ai e hana i ka hōʻailona SIGKILL :)
Pehea e hoʻoponopono ai i ka pilikia?
ʻO ke ala maʻalahi loa e pale aku i kahi kaʻina mai ka pepehi ʻia ʻana, ʻo ia ke pani i ka pointer hana ma ka papa kelepona ʻōnaehana. ʻO ka mea pōʻino, he mea koʻikoʻi kēia ala no nā kumu he nui.
ʻO ka mea mua, ʻaʻole pilikino ka hōʻailona e hoʻomalu i ka wahi hoʻomanaʻo o sysent i ka hōʻailona kernel XNU, akā ʻaʻole hiki ke loaʻa i nā hōʻailona kernel. Pono ʻoe e hoʻohana i nā ʻano hulina heuristic, e like me ka wehe ʻana i ka hana a me ka ʻimi ʻana i kahi kuhikuhi i loko.
ʻO ka lua, ʻo ke ʻano o nā mea hoʻokomo i ka papaʻaina e pili ana i nā hae i hoʻohui ʻia ai ka kernel. Inā hōʻike ʻia ka hae CONFIG_REQUIRES_U32_MUNGING, e hoʻololi ʻia ka nui o ka hale - e hoʻohui ʻia kahi kahua hou.
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
*/
};
ʻO ka mea pōmaikaʻi, i nā mana hou o macOS, hāʻawi ʻo Apple i API hou no ka hana ʻana me nā kaʻina hana. Hāʻawi ka Endpoint Security API i nā mea kūʻai aku e ʻae i nā noi he nui i nā kaʻina hana ʻē aʻe. No laila, hiki iā ʻoe ke pale i nā hōʻailona i nā kaʻina hana, me ka hōʻailona SIGKILL, me ka hoʻohana ʻana i ka API i ʻōlelo ʻia ma luna.
#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;
}
Pēlā nō, hiki ke hoʻopaʻa inoa ʻia kahi kulekele MAC i loko o ka kernel, e hāʻawi ana i kahi ala palekana hōʻailona (policy proc_check_signal), akā ʻaʻole kākoʻo ʻia ka API.
Palekana hoʻonui kernel
Ma waho aʻe o ka pale ʻana i nā kaʻina hana i loko o ka ʻōnaehana, pono pū ka pale ʻana i ka hoʻonui kernel ponoʻī (kext). Hāʻawi ka macOS i kahi hoʻolālā no nā mea hoʻomohala e hoʻomohala maʻalahi i nā mea hoʻokele IOKit. Ma waho aʻe o ka hāʻawi ʻana i nā mea hana no ka hana ʻana me nā polokalamu, hāʻawi ʻo IOKit i nā ala no ka hoʻokele hoʻokele me ka hoʻohana ʻana i nā manawa o nā papa C++. Hiki i kahi noi ma ka mea hoʻohana ke "loaʻa" i kahi mea i hoʻopaʻa inoa ʻia o ka papa e hoʻokumu i kahi pilina kernel-userspace.
No ka ʻike ʻana i ka helu o nā manawa papa i ka ʻōnaehana, aia ka pono ioclasscount.
my_kext_ioservice = 1
my_kext_iouserclient = 1
ʻO kēlā me kēia hoʻonui kernel e makemake ana e hoʻopaʻa inoa me ka mea hoʻokele kaʻa, pono e haʻi i kahi papa i hoʻoilina mai IOService, no ka laʻana my_kext_ioservice ma kēia hihia.
Ke ho'āʻo nei e wehe i kahi mea hoʻokele mai ka ʻōnaehana (kextunload command), ua kapa ʻia ka hana virtual "bool terminate (IOOptionBits options)". Ua lawa ka hoʻihoʻi hewa ʻana i ke kelepona e hoʻopau i ka wā e hoʻāʻo ai e wehe i ka kextunload.
bool Kext::terminate(IOOptionBits options)
{
if (!IsUnloadAllowed)
{
// Unload is not allowed, returning false
return false;
}
return super::terminate(options);
}
Hiki ke hoʻonoho ʻia ka hae IsUnloadAllowed e ka IOUserClient ke hoʻouka. Ke loaʻa kahi palena hoʻoiho, e hoʻihoʻi ke kauoha kextunload i kēia huahana:
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.
Pono e hana ʻia ka pale like no IOUserClient. Hiki ke hoʻokuʻu ʻia nā manawa o nā papa me ka hoʻohana ʻana i ka hana hoʻohana IOKitLib "IOCatalogueTerminate (mach_port_t, uint32_t hae, io_name_t wehewehe);". Hiki iā ʻoe ke hoʻihoʻi hewa i ke kāhea ʻana i ke kauoha "hoʻopau" a hiki i ka "make" o ka mea hoʻohana, ʻo ia hoʻi, ʻaʻole i kapa ʻia ka hana "clientDied".
Mālama waihona
No ka pale ʻana i nā faila, ua lawa ka hoʻohana ʻana i ka Kauth API, kahi e hiki ai iā ʻoe ke kaupalena i ke komo ʻana i nā faila. Hāʻawi ʻo Apple i nā mea hoʻomohala me nā hoʻolaha e pili ana i nā hanana like ʻole i ka laulā; no mākou, he mea nui nā hana KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a me KAUTH_VNODE_DELETE_CHILD. ʻO ke ala maʻalahi loa e kaupalena i ke komo ʻana i nā faila ma ke ala - hoʻohana mākou i ka API "vn_getpath" e kiʻi i ke ala i ka faila a hoʻohālikelike i ka prefix ala. E hoʻomaopopo i ka hoʻololi ʻana i ka inoa o nā ala waihona waihona, ʻaʻole ʻae ka ʻōnaehana i ke komo ʻana i kēlā me kēia faila, akā i ka waihona ponoʻī i kapa hou ʻia. Pono e hoohalike i ke ala makua a kaohi ia KAUTH_VNODE_DELETE no ia mea.
ʻO ka hemahema o kēia ʻano hana haʻahaʻa paha i ka piʻi ʻana o nā prefixes. No ka hōʻoia ʻana ʻaʻole like ka hoʻohālikelike ʻana me O(prefix*length), kahi prefix ka helu o nā prefixes, ʻo ka lōʻihi ka lōʻihi o ke kaula, hiki iā ʻoe ke hoʻohana i ka deterministic finite automaton (DFA) i kūkulu ʻia e nā prefixes.
E noʻonoʻo kākou i ke ʻano o ke kūkulu ʻana i kahi DFA no kahi hoʻonohonoho prefix i hāʻawi ʻia. Hoʻomaka mākou i nā cursors ma ka hoʻomaka o kēlā me kēia prefix. Inā kuhikuhi nā ʻōkuhi a pau i ke ʻano hoʻokahi, a laila e hoʻonui i kēlā me kēia pehu i hoʻokahi ʻano a e hoʻomanaʻo i ka lōʻihi o ka laina hoʻokahi i ʻoi aku ka nui o ka laina hoʻokahi. Inā ʻelua mau ʻōkuhi me nā hōʻailona like ʻole, e hoʻokaʻawale i nā cursors i mau pūʻulu e like me ka hōʻailona a lākou e kuhikuhi ai a hana hou i ka algorithm no kēlā me kēia hui.
I ka hihia mua (ʻo nā huaʻōlelo āpau ma lalo o nā cursors ua like ia), loaʻa iā mākou kahi mokuʻāina DFA i hoʻokahi wale nō hoʻololi ma ka laina like. Ma ka hihia ʻelua, loaʻa iā mākou kahi papa o nā hoʻololi o ka nui 256 (helu o nā huaʻōlelo a me ka helu kiʻekiʻe o nā pūʻulu) i nā mokuʻāina i loaʻa ma ke kāhea ʻana i ka hana.
E nānā kākou i kekahi laʻana. No kahi hoʻonohonoho prefixes (“/foo/bar/tmp/”, “/var/db/foo/”, “/foo/bar/aba/”, “foo/bar/aac/”) hiki iā ʻoe ke loaʻa i kēia mau mea. DFA. Hōʻike ke kiʻi i nā hoʻololi e alakaʻi ana i nā mokuʻāina ʻē aʻe; ʻaʻole e pau nā hoʻololi ʻē aʻe.
Ke hele nei ma nā mokuʻāina DKA, aia paha he 3 mau hihia.
- Ua hōʻea ka mokuʻāina hope - pale ʻia ke ala, kaupalena mākou i nā hana KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a me KAUTH_VNODE_DELETE_CHILD
- ʻAʻole i hiki ke kūlana hope, akā "ua pau" ke ala (ua hiki i ka null terminator) - he makua ke ala, pono e kaupalena iā KAUTH_VNODE_DELETE. E hoʻomaopopo inā he waihona ʻo vnode, pono ʻoe e hoʻohui i kahi '/' ma ka hopena, i ʻole e kaupalena ʻia ia i ka faila "/foor/bar/t", ʻaʻole pololei.
- ʻAʻole i hiki ke kūlana hope, ʻaʻole i pau ke ala. ʻAʻohe o nā prefix e like me kēia, ʻaʻole mākou e hoʻokomo i nā mea kapu.
hopena
ʻO ka pahuhopu o nā hoʻonā palekana e hoʻomohala ʻia e hoʻonui i ka pae o ka palekana o ka mea hoʻohana a me kāna ʻikepili. Ma kekahiʻaoʻao, ua hoʻokōʻia kēia pahuhopu e ka hoʻomohalaʻana i ka huahana polokalamu Acronis, kahi e pani ai i kēlā mau nāwaliwali kahi i "nāwaliwali" ai ka'ōnaehana hana. Ma ka ʻaoʻao ʻē aʻe, ʻaʻole pono mākou e haʻalele i ka hoʻoikaika ʻana i kēlā mau mea palekana e hiki ke hoʻomaikaʻi ʻia ma ka ʻaoʻao OS, ʻoi aku ka nui o ka pani ʻana i kēlā mau nāwaliwali e hoʻonui i ko mākou kūpaʻa ponoʻī ma ke ʻano he huahana. Ua hōʻike ʻia ka nāwaliwali i ka Apple Product Security Team a ua hoʻopaʻa ʻia ma macOS 10.14.5 (https://support.apple.com/en-gb/HT210119).
Hiki ke hana i kēia mau mea inā ua hoʻokomo ʻia kāu pono i loko o ka kernel. ʻO ia hoʻi, ʻaʻohe puka puka no waho a me nā polokalamu makemake ʻole. Eia naʻe, e like me kāu e ʻike ai, ʻo ka pale ʻana i nā polokalamu kūpono e like me ka antivirus a me nā ʻōnaehana backup pono e hana. Akā i kēia manawa e loaʻa i nā huahana Acronis hou no ka macOS ka pale hou mai ka wehe ʻana mai ka ʻōnaehana.
Source: www.habr.com