The syswire Task
syswire is a tawon directive that produces a stream of system calls based on the caller’s current capabilities and a list of tripwire and context syscalls. (See the syscalls task page for more detail on Linux syscalls and capabilities.)
syswire uses a tripwire mechanism that ensures no traces will start until a privileged process calls a suspect syscall. For example a process with the cap_net_raw effective capability calling the socket syscall could trigger a trace of the process' next n syscalls, where both n and the exact syscalls are configurable by the user. The triggering capability, tripwire syscall, context syscalls, and duration are all configurable at runtime.
Glossary
Benign: A process state from the perspective of the syswire task. Benign Processes are processes that called a tripwire syscall, but do not have the user-defined elevated capability in their permitted capability set, which makes it impossible for them to acquire and use the capability. Processes in the Benign state that have been in that state for longer than maxage seconds will get aged off after evictrate seconds and returned to the Unknown State.[1]
Context Syscalls: A subset of syscalls that will be traced after a tripwire syscall is called by a process with elevated capabilities.
Dormant: A process state from the perspective of the syswire task. Dormant Processes are processes that called a tripwire syscall, do have the user-defined elevated capability in their permitted capability set, but do not have them in their effective capabilities, which makes it possible for them to eventually acquire and use the capability. Processes in the Dormant state that have been in that state for longer than maxage seconds will get aged off after evictrate seconds and returned to the Unknown State.
Elevated: We say a container has elevated privileges if it has enabled effective capabilities that were defined and configured at runtime. For example, the user can define both cap_sys_admin and cap_net_raw as elevated for a single run of syswire.
Traced: A process state from the perspective of the syswire task. Traced processes have been recently traced. Processes in the Traced state that have been in that state for longer than maxage seconds will get aged off after evictrate seconds and returned to the Unknown state
Tracing: A process state from the perspective of the syswire task. Processes in the Tracing state are currently being traced. i.e. syswire is producing syscall events for the process. Processes in Tracing that have been in that state for longer than maxage seconds will get aged off after maxtrace events have been produced or after maxage seconds. The process will then be put in the Traced state.
Tripwire Syscalls: A subset of syscalls that, when paired with the observation of an elevated capability, will trigger a trace of all tripwire and context syscalls.
Unknown: A process state from the perspective of the syswire task. syswire has no record of Unknown processes. It might be the case that the process has cycled through the other states (above) and aged off into Unknown.
Configuration options
tripwires-
tripwiresdefines thetripwiresubset of syscalls that, when paired with the observation of anelevatedcapability, will trigger a trace oftripwireandcontextsyscalls. Can be configured for multiple syscalls using a '+' separated list. (e.g.: read+write+open) capabilities-
capabilitiesdefines the capabilities that will be interpreted aselevatedduring a syswire task (e.g. cap_net_raw, cap_sys_ptrace, etc…). Can be configured for multiple syscalls using a '+' list.(e.g.: cap_net_raw+cap_sys_ptrace) context-
contextA subset of syscalls that will be traced after atripwiresyscalls is called by a process withelevatedcapabilities. Can be configured for multiple syscalls using a '+' separated list. (e.g.: read+write+open) maxtrace-
maxtracedefines the maximum number ofcontextevents generated from a process before it is changed to thetracedstate. For example a maxtrace of 0 will result in traces that only contain thetripwiresyscall while a maxtrace of 1 will result in traces that contain thetripwiresyscall and 1contextsyscall. (defaults to 0 events) evictrate-
evictratedefines the frequency, in seconds, that the task will check the age of all the processes it’s tracking and change the state if necessary, fromTracedtoUnknown, for example. (defaults to 5 seconds) maxage-
maxagedefines the amount of time, in seconds, a process stays in theBenign,Traced,Dormant, orTracingstate. (defaults to 5 seconds) meta-
default ""Meta allows you configure exactly what metadata (process, container, and pod info) will be published with the payload message. See Configuring the meta Field for more information.For example:
meta: process.name+pod.min
Sample Command Lines
The example below will launch a syswire task that tripwires on the cap_sys_ptrace capability and the capset syscall. Any process with the cap_sys_ptrace activated in their effective capabilities that calls the capset syscall will be traced. The trace will consist of 5 events containing the subsequent capset, ptrace, read, and write syscalls. Every 5 seconds, the task will move benign, traced, dormant processes older than 40 seconds to the unknown state.
tawonctl d sub -c "process.pid:54321" -t "syswire|capabilities:cap_sys_ptrace;tripwires:capset;context:ptrace+read+write;max_trace:5"
The example below will launch a syswire task that tripwires on the cap_net_raw capability and the socket syscall. Any process with the cap_net_raw activated in their effective capabilities that calls the socket syscall will be traced. The trace will consist of 20 events containing the subsequent socket syscalls. Every 5 seconds, the task will move benign, traced, dormant processes older than 40 seconds to the unknown state.
tawonctl d sub -c "process.pid:*" -t "syswire|capabilities:cap_net_raw;tripwires:socket;context:socket;maxtrace:20;maxage:40;evictrate:5"
The example below will launch a syswire task that tripwires on the cap_sys_ptrace or the cap_net_raw capabilities and the ptrace or socket syscalls. Any process with the cap_sys_ptrace or cap_net_raw activated in their effective capabilities that calls the socket or ptrace syscall will be traced. The trace will consist of 10 context events containing sendto, ioctl, process_vm_readv, process_vm_writev, ptrace, socket, and ptrace syscalls. Every 5 seconds, the task will move benign, traced, and dormant processes older than 30 seconds to the unknown state.
tawonctl d sub -c "process.name:~simulator" -t "syswire|capabilities:cap_sys_ptrace+cap_net_raw;tripwires:ptrace+socket;context:sendto+ioctl+process_vm_readv+process_vm_writev+ptrace;maxtrace:10;maxage:30
Output
json schema
{
"type": "object",
"properties": {
"process": {
"type": "object",
"properties": {
"cmd": {
"type": "string",
"description": "the text of the command"
},
"exe": {
"type": "string",
"description": "the path to the executable"
},
"name": {
"type": "string",
"description": "the process name"
},
"ns": {
"type": "string",
"description": "namespace"
},
"pid": {
"type": "integer",
"description": "process ID"
},
"pid": {
"type": "integer",
"description": "parent process ID"
},
"startedAt": {
"type": "string",
"description": "the time the process was started"
}
}
},
"context": {
"type": "array",
"items": {
"$ref": "#/$defs/function"
}
},
"tripwire": {
"$ref": "#/$defs/function"
}
},
"$defs": {
"function": {
"type": "object",
"required": [
"args",
"syscall",
"timestamp"
],
"properties": {
"args": {
"$ref": "#/$defs/arguments"
},
"syscall": {
"type": "string",
"description": "The name of the function"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "The time of the function call"
}
}
},
"arguments": {
"type": "array",
"items": {
"$ref": "#/$defs/argument"
}
},
"argument": {
"properties": {
"name": {
"type": "string",
"description": "name of argument"
},
"value": {
"type": [
"integer",
"string",
"object"
],
"description": "scalar, string, or json representation of object"
}
}
}
}
}
Sample output
{
"context":[
{
"args":{
"addr":1,
"data":824635800144,
"pid":967,
"request":16900
},
"syscall":"ptrace",
"timestamp":"2024-07-23T14:48:39Z"
},
{
"args":{
"addr":0,
"data":0,
"pid":967,
"request":17
},
"syscall":"ptrace",
"timestamp":"2024-07-23T14:48:43Z"
},
{
"args":{
"addr":0,
"data":0,
"pid":967,
"request":16
},
"syscall":"ptrace",
"timestamp":"2024-07-23T14:48:43Z"
}
],
"process":{
"cmd":"./simulator capSet -l -p 967",
"exe":"/home/luay/projects/mantisnet/simulator/simulator",
"name":"simulator",
"ns":"4-4026531840",
"pid":110686,
"ppid":101449,
"startedAt":"2024-07-23T14:48:37Z"
},
"tripwire":{
"args":{
"buf":"",
"count":0,
"fd":0
},
"syscall":"read",
"timestamp":"1970-01-01T00:00:00Z"
}
}
Fields
syscall-
mapHolds the syscalls output. syscall.args-
mapHolds the syscall argument names and values. syscall.args.name-
stringHolds the name of the syscall argument. syscall.args.value-
stringHolds the name of the syscall argument. syscall.function-
string|uint64Holds the valueof the syscall argument. syscall.process-
mapHolds the Process information. syscall.process.pid-
uint32Process PID. syscall.process.ppid-
uint32Process Parent PID. syscall.process.name-
stringProcess name. syscall.process.cmd-
stringCommand line string. syscall.process.exe-
stringExecutable name. syscall.process.ns-
stringNamespace in the format of {device ID}-{inode number}. syscall.process.startedAt-
stringTime the process started. syscall.process.container-
mapContainer information for process (if it is a container). syscall.process.container.ID-
stringID of Container. syscall.process.container.Name-
stringName of Container.