Quam custodire processus et extensiones nuclei in macOS

Salve, Habr! Hodie loqui vellem quomodo processus ab oppugnationibus ab oppugnatoribus in macOS tueri potes. Exempli gratia, hoc utile est ad systema antivirum vel tergum, praesertim cum sub macOS plures sunt modi processus "occidere". Lege de hoc et tutelae modos sub inciso.

Quam custodire processus et extensiones nuclei in macOS

In classic ut "occidere" est processus

Nota via ad processum "occidere" est signum processus mittere SIGKILL. Per bash vocare potes vexillum "occidere -SIGKILL PID" vel "pkill -9 NAME" occidere. Mandatum "occidere" ex diebus UNIX cognitum est et praesto non solum in macOS, sed etiam in aliis systematis unix similibus.

Sicut in systematis UNIX-similis, macOS permittit ut aliqua signa processus intercipias praeter duos - SIGKILL et SIGSTOP. Hic articulus imprimis signum SIGKILL intendunt tamquam signum qui processus occidendi causat.

macOS specialia

In macOS, systematis occidentis vocatum in XNU kernel vocat functionem psignalem (SIGKILL,....). Experiamur videre quaenam aliae actiones in usoris usoris in usorum usorum spatio a functione psigna vocentur. Eamus viriditas vocat ad psigna functionem in machinationibus internis nuclei (quamvis non levia sint, relinquemus eas ad alium articulum - subscriptio verificationis, errorum memoria, exitus/terminus pertractatio, fasciculi tutelae violationes, etc. .

Recognitio incipiamus cum munere ac respondente systemate vocationis terminate_with_payload. Ex his constare potest quod praeter vocationem classicorum occisorum accessus alternus est qui ad macOS systematis operantis specificus est et in BSD non invenitur. Principia operativa utriusque systematis etiam similia sunt. Directae sunt vocat ad munus nuclei psigna. Etiam nota quod antequam processus occidat, perscriptio "cansignalis" perficitur - num processus signum ad alium processum mittere potest, ratio nullam applicationem processuum systematis occidendi patitur, exempli gratia.

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);
	}
...
}

deductae

Vexillum eundi ad daemones creandos ad systema satus et ad vitandum sistendum inducitur. Placere note fontes in antiqua versione launchctl usque ad macOS 10.10 esse, exempla in codice ad usus illustrandos suppeditantur. Moderni launchctl signa deductae per XPC mittit, logica launchctl ad eam mota est.

Intueamur quomodo prorsus applicationes reprimantur. Antequam SIGTERM signum mittat, applicatio ad "proc_terminatam" rationem vocationis adhibita obstruatur.

<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));
		} 
...
<>

Sub cucullo proc_terminato, non obstante nomine, potest non solum psigna cum SIGTERM mittere, sed etiam SIGKILL.

Indirect Interfice - Resource Limit

Plus interesting causa videri potest in alia vocatione systematis process_policy. Communis usus huius systematis vocationi est ut facultates applicationis circumscribat, ut indicem temporis ac memoriam quotas CPU finiat ut systema notabiliter retardetur in operationibus file caching. Si applicatio ad limitem resource suae pervenerit, ut videri potest ex functionis actuum_resource_actionum, signum SIGKILL processui mittitur.

Etsi haec ratio vocationis processum potentia interficere potuit, ratio iura processus vocationis systematis vocationis satis non repressit. Nam reprehendo fuitsed satis est PROC_POLICY_ACTION_SET utendi hac condicione utatur.

Hinc, si "limes" applicationis usus quota CPU (exempli gratia tantum 1 ns currere permittens), tunc quemlibet processum in systemate occidere potes. Sic, quemlibet processum in systematis, incluso processu antiviro, interficere potest. Interesting etiam effectus qui fit cum processum interficiens cum pid 1 (launchctl) - panicum nuclei cum signo processus quaerit :) SIGKILL

Quam custodire processus et extensiones nuclei in macOS

Quam quaestionem solvere?

Rectissima via est ne processus ne occidatur, monstratorem munus reponere in tabula vocationis systematis. Dolendum est, haec methodus multis de causis non levis est.

Primum, symbolum quod situm memoriae sistens moderatur, symbolo XNU nucleo privatim non solum est, sed in symbolis nucleis inveniri non potest. Modis inquisitionis heuristicis uti debebis, ut munus dynamice disgreges et monstratorem in eo perseveres.

Secundo, structura viscus mensae dependet a vexillis quibus acinum confectum est. Si CONFIG_REQUIRES_U32_MUNGING vexillum declaratur, magnitudo structurae mutabitur - accessus adicietur ager sy_arg_munge32. Additamentum perscriptio explere necesse est ut uter vexillum nuclei confectum sit, vel etiam munus indicibus notis contra notas inspicias.

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
                                         */
};

Fortunate, in recentioribus versionibus macOS, Apple novum API praebet processibus operandi. Endpoint Securitatis API clientibus permittit ut multas petitiones aliis processibus permittat. Sic signa processuum obstruere potes, signo SIGKILL excepto, utens supra memorato 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;
}

Similiter, MAC Policy in nucleo describi potest, quae modum tutelae insignem praebet (consilium proc_check_signal), sed API publice non sustinetur.

Kernel extensio praesidium

Praeter processuum in systemate tuendo, ipsum extensio nuclei tutandi (kext) etiam necessaria est. macOS compagem tincidunt praebet ut rectores fabrica facile evolvere IOKit. Praeter instrumenta ad fabricandas machinas comparandas, IOKit methodos agitatorie positis adhibitis generibus C++ instantiarum. Applicatio in usoris usoris instantia poterit "invenire" descripserunt instantia ordinis ad relationem nuclei usoris constituendam.

Ad numerum instantiarum classium deprehendendum in systemate, utilitas est ioclasscount.

my_kext_ioservice = 1
my_kext_iouserclient = 1

Extensio nuclei quaevis quae cum acervo exactoris subcriptio vult declarare debet genus quod hereditas ab IOService, exempli gratia my_kext_ioserviendi in hoc casu. Applicationes usoris coniunctae causat novam instantiam classis hereditantis ab IOUserClient, in exemplo my_kext_iouserclient.

Cum coegi ex ratio (kextunload mandatum), munus virtuale "bool terminare (IOOptionBits optiones)" vocatur. Satis est falsa reddere in vocatione terminare, cum kextunload inactivandi exonerare conatur.

bool Kext::terminate(IOOptionBits options)
{

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

  return super::terminate(options);
}

Vexillum IsUnloadAllowed ab IOUserClient cum oneratum apponi potest. Cum terminus download est, mandatum kextunload sequenti output reddet:

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.

Similia praesidia facienda sunt IOUserClient. Instantiae classes exonerare possunt utentes IOKitLib functionis usoris "IOCatalogueTerminate(mach_port_t, uint32_t vexillum, io_name_t description);". Falsum reddere potes cum mandatum vocans "terminate" donec applicationis usoris "moritur", id est munus "clientDied" non vocatur.

File praesidium

Ad tabulas tuendas, Kauth API uti satis est, qui te aditum ad lima restringere sinit. Lacus tincidunt notificationes de variis eventibus in ambitu praebet: nobis operationes KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA et KAUTH_VNODE_DELETE_CHILD magni momenti sunt. Facillima via ad restringere accessum ad files per semitam est - "vn_getpath" API utimur ut iter ad limam et viam praepositionem comparemus. Nota ad optimize semitas tabulariorum renascentias, ratio non permittit accessum ad singulas tabulas, sed solum ad ipsum folder quod renominatum est. Est iter parentis comparare et restringere KAUTH_VNODE_DELETE necesse est pro ea.

Quam custodire processus et extensiones nuclei in macOS

Incommodum accessionis huius potest esse humilis effectus sicut numerus praefixionum augetur. Ut comparatio non sit aequalis O (praepositionis longitudinis), ubi praepositio est numerus praefixionum, longitudo est chordi, uti potes automaton finitum (DFA) a praefixis determinatum uti.

Methodum inspiciamus construendi DFA pro certo praefixorum statuto. Cursores initializemus in initio cuiusque praepositionis. Si cursores omnes ad eandem indolem designant, tum unumquemque cursorem uno charactere auge, et memento longitudinem lineae una esse maiorem. Si cursores duo sunt cum diversis figuris, cursores in circulos dividunt secundum symbolum demonstrant et algorithmum pro singulis coetus repetere.

In primo casu (omnes characteres sub cursoribus eaedem sunt), statum DFA habemus, qui unum tantum transitum in eadem linea habet. In secundo casu tabulam transitus quantitatis 256 (numerus characterum et numerus maximorum coetuum accipimus) ad status subsequentes obtinet munus vocando recursive.

Intueamur exemplum. Pro statuto praefixionum ("/foo/bar/tmp/", "/var/db/foo/", "/foo/bar/aba/", "foo/bar/aac/") licebit sequentia DFA. Figura demonstrat tantum transitiones ad alios status, aliae transitus non erunt finales.

Quam custodire processus et extensiones nuclei in macOS

Cum per civitates DKA agatur, possunt esse 3 casus.

  1. Ultimum statum perventum est - semita munitur, operationes KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA et KAUTH_VNODE_DELETE_CHILD limitamus
  2. Ad extremum statum non perventum est, sed semita "finiit" (in nullo termino perventum est) - semita est parens, KAUTH_VNODE_DELETE limitare necesse est. Nota quod si vnode est folder, debes addere "/' in fine, alioquin eam finire potest tabella "/foor/bar/t", quod falsum est.
  3. Ad summam non pervenit, semita non finitur. Nihil praefixionum huic uni congruit, restrictiones nos non introducas.

conclusio,

Propositum solutionis securitatis augere est gradum securitatis utentis eiusque notitia augere. Ex altera parte, hic finis evolutionis Acronis producti programmatis perficitur, quod vulnerabilitates claudit ubi ipsa ratio operandi est "debilis". Ex altera parte, non omittamus illas rationes securitatis confirmari quae in OS parte emendari possunt, praesertim cum talis vulnerabilitas occlusio nostram augeat stabilitatem ut opus. Nuditate relata est Apple Product Securitatis Team et in macOS 10.14.5 (https://support.apple.com/en-gb/HT210119) relatum est.

Quam custodire processus et extensiones nuclei in macOS

Haec omnia solum fieri possunt si utilitas tua in nucleum publice instituatur. Hoc est, nullae tales densi sunt pro programmate externo et inutile. Nihilominus, ut vides, etiam legitimas programmata custodiens sicut systemata antivirus et tergum opus requirit. Nunc autem nova Acronis producta pro macOS additae tutelae contra exonerationes systematis habebuntur.

Source: www.habr.com

Add a comment