3.2 kacs.audit.descriptor.changed

  • Event type: kacs.audit.descriptor.changed
  • Defined in: kacs.evman
  • Tier: essential
  • Gating: a change that includes the SACL, always; any other change when the rights it needed overlap the alarm mask on the handle it was made through
  • Cardinality: once per authorised change

The record that a caller changed, or was authorised to change and failed to change, the security descriptor of a file, a token, a process or a System V IPC object. Registry keys have their own record of the same shape, lcs.audit.key.descriptor.changed.

A change to a SACL is always recorded, whatever the old or new descriptor says. Changing a SACL needs ACCESS_SYSTEM_SECURITY, which needs SeSecurityPrivilege; it is rare; and removing one is how an intruder stops being watched. Before this record existed a file's SACL could be removed in silence, because the only audit of a descriptor change was evaluated against the new SACL, which then had nothing in it.

Any other change — the owner, the group, the DACL, the integrity label — is recorded when the rights it needed overlap the alarm mask on the handle it was made through: the rule kacs.audit.handle.used follows. Only a file handle carries such a mask, so for a token, a process or an IPC object only a SACL change is recorded.

The descriptors themselves are not carried, only their SHA-256 digests, lengths and owners. Equal digests mean the change rewrote the descriptor without altering it.

3.2.1 Fields #

FieldTypePresenceMeaning
subject.token.sidbin.sidvia subjectThe user SID of the effective token the operation ran under.
subject.token.groupsbin.sid[]via subjectThe group SIDs carried by the effective token.
subject.token.group-attributesuint.flags[]via subjectPer-group attribute bitmasks, positionally parallel to subject.token.groups.
subject.token.integrityuint.integrityvia subjectThe integrity RID of the effective token.
subject.token.iduint.luidvia subjectThe token's own LUID, identifying this specific token rather than the logon session it belongs to.
subject.token.auth-iduint.luidvia subjectThe LUID of the logon session the effective token belongs to.
subject.token.typestr.enumvia subjectWhether the effective token is a primary token or an impersonation token.
subject.token.impersonationuint.enumvia subjectThe impersonation level of the effective token.
subject.token.uiduintvia subjectThe Linux UID this token projects onto, for correlating a Peios event with Linux-side audit data.
emitter.process.piduintvia subjectThe process ID the record was written from.
emitter.process.namestrvia subjectThe kernel's name for the emitting process, typically the executable's basename.
emitter.process.executablestr.pathvia subjectThe path the emitting process was executed from, resolved at exec with symbolic links already followed.
subject.pip.typeuint.enumvia subjectThe Protected Isolated Process type in force for the access check.
subject.pip.trustuintvia subjectThe PIP trust level in force for the access check.
object.kindstr.enumrequiredfile, token, process or ipc.
object.file.pathstr.pathoptionalOn a file, its absolute path, when the handle's path could be resolved.
object.token.iduint.luidwhen object.kind == tokenThe LUID of the token the operation acted on, for token-open and token-adjust checks.
object.token.guidbin.guidwhen object.kind == tokenThe durable GUID of the token the operation acted on.
object.process.guidbin.guidwhen object.kind == processThe durable GUID of the process the operation acted on.
object.ipc.typestr.enumwhen object.kind == ipcWhich kind of System V IPC object the operation acted on: a semaphore set, a shared-memory segment or a message queue.
object.ipc.idintwhen object.kind == ipcThe System V IPC identifier of the object, as semget, shmget or msgget returned it.
object.sd.componentsuint.flagsrequiredThe parts the caller set. A SACL bit means the record was not discretionary: such a change is always recorded.
object.sd.lengthuint.byteswhen outcome.success == trueThe byte length of the object's security descriptor.
object.sd.digestbinwhen outcome.success == trueSHA-256 of the descriptor as written.
object.sd.ownerbin.sidoptionalThe owner of the descriptor written, when it has one.
object.sd.length-previousuint.bytesoptionalThe byte length of the descriptor a change replaced.
object.sd.digest-previousbinoptionalSHA-256 of the descriptor replaced. Absent, with its length and owner, where the object had no stored descriptor to replace.
object.sd.owner-previousbin.sidoptionalThe owner SID a change replaced.
access.requesteduint.maskrequiredThe rights the change needed: WRITE_OWNER, WRITE_DAC, ACCESS_SYSTEM_SECURITY, as the parts set ask.
access.granteduint.maskoptionalWhat the handle the change was made through was opened with. Absent on a change made without one.
access.audit-maskuint.maskoptionalThe alarm mask on that handle.
access.matcheduint.maskoptionalThe part of access.requested the alarm mask matched, on a change made through a handle: zero when only the SACL made the record exist.
outcome.successboolrequiredWhether the new descriptor was written. A refused change — one the caller had no right to make — is not this record; it is the access check's.
outcome.errnoint.errnowhen outcome.success == falseThe error the operation failed with, as a negative errno.

Every record also carries the header fields of the envelope, which no payload repeats.

Generated from kacs.evman by pkm/tools/gen-events-book.py. Edit the fragment, not this page.

Edit this page