Getting Started
Installation¶
Syscall Monkey is written in Go, and there are a few different ways you can get started.
Binary¶
You can build the binary from the source:
git clone https://github.com/syscallmonkey/monkey.git
cd monkey
make bin/monkey
./bin/monkey -h
Note, that if you're running on MacOS, you can build for Linux, but unfortunately MacOS's version of ptrace
doesn't allow any of this magic to happen.
Pull Docker container¶
When using with Kubernetes, you can use our official docker images.
docker pull ghcr.io/syscallmonkey/monkey:0.0.1rc1
Check the latest available versions here.
Note, that these container builds are minimal, and don't include things like bash.
$ docker run --rm -ti --cap-add SYS_PTRACE ghcr.io/syscallmonkey/monkey:0.0.1 -h
Usage:
monkey [OPTIONS]
Application Options:
-p, --attach= Attach to the specified pid
-t, --target= Attach to process matching this name
-c, --config= Configuration file with desired scenario
-o, --output= Write the tracing output to the file (instead of stdout)
-C, --summary Show verbose debug information
-s, --silent Don't display tracing info
Help Options:
-h, --help Show this help message
Building Docker container¶
If you're like to build the container locally from the source, it's easy:
git clone https://github.com/syscallmonkey/monkey.git
cd monkey
make build
make run
make run
is a shortcut that will start the newly built image and run a bash session inside:
root@3e14fcd5843c:/# monkey -h
Usage:
monkey [OPTIONS]
Application Options:
-p, --attach= Attach to the specified pid
-t, --target= Attach to process matching this name
-c, --config= Configuration file with desired scenario
-o, --output= Write the tracing output to the file (instead of stdout)
-C, --summary Show verbose debug information
-s, --silent Don't display tracing info
Help Options:
-h, --help Show this help message
Compatibility¶
Currently, only Linux
on x86_64
is supported. If you need arm support, file an issue.
Running Syscall Monkey¶
There are two ways of running Syscall Monkey:
- start a process (append the command at the end)
- attach to a running process (
-p
flag)
Start a new process¶
To start a new process and manipulate it, just append the command at the end of the monkey
command.
What you're going to see is the list of all syscalls
made by the program, printed in the following format:
SYSCALL_NAME(ARG_NAME=ARG_VALUE) = RETURN_CODE (OPTIONALLY ERROR DESCRIPTION)
For example, let's see what syscalls
a simple sleep 1
makes:
root@c69219c773ff:/# monkey sleep 1
Version v0.0.1, build Sat Jul 17 10:30:03 UTC 2021
Started new process pid 21
execve(filename=NULL, argv=0, envp=0) = 0
brk(brk=0) = 94331848404992
arch_prctl(task=12289, code=140722511137424, addr=140631102649024) = -1 (errno 22: invalid argument)
access(filename=/etc/ld.so.preload, mode=4) = -1 (errno 2: no such file or directory)
openat(dfd=4294967196, filename=/etc/ld.so.cache, flags=524288, mode=0) = 3
fstat(fd=3, statbuf=140722511133840) = 0
mmap(addr=0, len=6530, prot=1, flags=2, fd=3, off=0) = 140631102525440
close(fd=3) = 0
openat(dfd=4294967196, filename=/lib/x86_64-linux-gnu/libc.so.6, flags=524288, mode=0) = 3
read(fd=3, buf=, count=832) = 832
pread64(fd=3, buf=, count=784, pos=64) = 784
pread64(fd=3, buf=, count=32, pos=848) = 32
pread64(fd=3, buf=, count=68, pos=880) = 68
fstat(fd=3, statbuf=140722511133920) = 0
mmap(addr=0, len=8192, prot=3, flags=34, fd=4294967295, off=0) = 140631102517248
pread64(fd=3, buf=, count=784, pos=64) = 784
pread64(fd=3, buf=, count=32, pos=848) = 32
pread64(fd=3, buf=, count=68, pos=880) = 68
mmap(addr=0, len=2036952, prot=1, flags=2050, fd=3, off=0) = 140631100477440
mprotect(start=140631100628992, len=1847296, prot=0) = 0
mmap(addr=140631100628992, len=1540096, prot=5, flags=2066, fd=3, off=151552) = 140631100628992
mmap(addr=140631102169088, len=303104, prot=1, flags=2066, fd=3, off=1691648) = 140631102169088
mmap(addr=140631102476288, len=24576, prot=3, flags=2066, fd=3, off=1994752) = 140631102476288
mmap(addr=140631102500864, len=13528, prot=3, flags=50, fd=4294967295, off=0) = 140631102500864
close(fd=3) = 0
arch_prctl(task=4098, code=140631102522752, addr=18446603442607026496) = 0
mprotect(start=140631102476288, len=12288, prot=1) = 0
mprotect(start=94331820990464, len=4096, prot=1) = 0
mprotect(start=140631102717952, len=4096, prot=1) = 0
munmap(addr=140631102525440, len=6530) = 0
brk(brk=0) = 94331848404992
brk(brk=94331848540160) = 94331848540160
clock_nanosleep(which_clock=0, flags=0, rqtp=140722511137168, rmtp=0) = 0
close(fd=1) = 0
close(fd=2) = 0
exit_group(error_code=0)
--- program exited ---
Let's take a look at an interesting lines.
access syscall¶
access
syscall check real user's permissions for a file. Its signature is:
int access(const char *pathname, int mode);
In the output, Syscall Monkey intercepted the syscall, and we can see that the program check the file /etc/ld.so.preload
, and it gets an error number 2 "no such file or directory":
access(filename=/etc/ld.so.preload, mode=4) = -1 (errno 2: no such file or directory)
Attaching to a running process¶
To attach to a process that's already running, you can specify the PID of the target via -p
flag. For example:
root@c69219c773ff:/# sleep 5&
[1] 10
root@c69219c773ff:/# monkey -p 10
...
restart_syscall() = 0
close(fd=1) = 0
close(fd=2) = 0
exit_group(error_code=0)
--- program exited ---
[1]+ Done sleep 5
Quick start¶
You now have a Syscall Monkey available. Here's a quick example to get you started:
Change the return value of geteuid¶
Use this scenario to sometimes change the user returned by getuid
:
# cat /etc/passwd
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/s
# bin:x:2:2:bin:/bin:/usr/sbin/nologin
# cat /examples/getuid-random.yml
rules:
- name: probably daemon
probability: 0.66
match:
name: geteuid
modify:
return: 1
- name: but maybe bin
probability: 0.5
match:
name: geteuid
modify:
return: 2
And this should be enough to confuse a lot of people:
root@f34cc94a6b6d:/# whoami
root
root@f34cc94a6b6d:/# monkey -s -c /examples/getuid-random.yml whoami
daemon
root@f34cc94a6b6d:/# monkey -s -c /examples/getuid-random.yml whoami
root
root@f34cc94a6b6d:/# monkey -s -c /examples/getuid-random.yml whoami
bin
Time for mischief!¶
This should be enough to get you started. Have fun!