From ac0198eed1cb32f6a8ada43b62a763e9c900480e Mon Sep 17 00:00:00 2001 From: GLVS Kiriti Date: Wed, 7 Aug 2024 22:20:19 +0530 Subject: [PATCH 1/3] Added helper functions for open openat openat2 syscalls DirectoryTraversalMonitoredFileRead rule is triggered Signed-off-by: GLVS Kiriti --- events/exampleyamlfile.yml | 21 ++++++--------------- pkg/declarative/helpers.go | 32 +++++++++++++++++++++++--------- pkg/declarative/host.go | 17 ++++++++++++++--- pkg/declarative/yamltypes.go | 12 ++++++++++-- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/events/exampleyamlfile.yml b/events/exampleyamlfile.yml index c483006d..04f380c3 100644 --- a/events/exampleyamlfile.yml +++ b/events/exampleyamlfile.yml @@ -1,23 +1,14 @@ tests: - - rule: WriteBelowRoot + - rule: DirectoryTraversalMonitoredFileRead runner: HostRunner before: "" steps: - - syscall: "write" + - syscall: "open" args: - filepath: "/root/created-by-event-generator" - content: "" - after: "rm -f /root/created-by-event-generator" - - - rule: WriteBelowEtc - runner: HostRunner - before: "" - steps: - - syscall: "write" - args: - filepath: "/etc/created-by-event-generator" - content: "" - after: "rm -f /etc/created-by-event-generator" + filepath: "/etc/../etc/../etc/shadow" + flag: 0 + mode: 0655 + after: "" - rule: LaunchIngressRemoteFileCopyToolsInsideContainer runner: ContainerRunner diff --git a/pkg/declarative/helpers.go b/pkg/declarative/helpers.go index 50ceb4e7..42cbf319 100644 --- a/pkg/declarative/helpers.go +++ b/pkg/declarative/helpers.go @@ -59,18 +59,32 @@ func CreateTarReader(filePath string) (io.Reader, error) { return tarBuffer, nil } -func WriteSyscall(filepath string, content string) error { - // Open the file using unix.Open syscall - fd, err := unix.Open(filepath, unix.O_WRONLY|unix.O_CREAT, 0644) +func OpenSyscall(filepath string, flags int, mode uint32) (int, error) { + fd, err := unix.Open(filepath, flags, mode) if err != nil { - return fmt.Errorf("error opening file: %v", err) + return -1, fmt.Errorf("error opening file: %v", err) + } + return fd, nil +} + +func OpenatSyscall(dirfd int, filepath string, flags int, mode uint32) (int, error) { + fd, err := unix.Openat(dirfd, filepath, flags, mode) + if err != nil { + return -1, fmt.Errorf("error opening file: %v", err) + } + return fd, nil +} + +func Openat2Syscall(dirfd int, filepath string, flags int, mode uint32, resolve uint64) (int, error) { + how := &unix.OpenHow{ + Flags: uint64(flags), + Mode: uint64(mode), + Resolve: resolve, } - defer unix.Close(fd) - // Write to the file using unix.Write - _, err = unix.Write(fd, []byte(content)) + fd, err := unix.Openat2(dirfd, filepath, how) if err != nil { - return fmt.Errorf("error writing to file: %v", err) + return -1, fmt.Errorf("error opening file: %v", err) } - return nil + return fd, nil } diff --git a/pkg/declarative/host.go b/pkg/declarative/host.go index 32147212..cd8ec914 100644 --- a/pkg/declarative/host.go +++ b/pkg/declarative/host.go @@ -35,9 +35,20 @@ func (r *Hostrunner) ExecuteStep(ctx context.Context, test Test) error { steps := test.Steps for _, step := range steps { switch step.Syscall { - case "write": - if err := WriteSyscall(step.Args["filepath"], step.Args["content"]); err != nil { - return fmt.Errorf("write syscall failed with error: %v", err) + case "open": + _, err := OpenSyscall(*step.Args.Filepath, *step.Args.Flags, *step.Args.Mode) + if err != nil { + return fmt.Errorf("open syscall failed with error: %v", err) + } + case "openat": + _, err := OpenatSyscall(*step.Args.Dirfd, *step.Args.Filepath, *step.Args.Flags, *step.Args.Mode) + if err != nil { + return fmt.Errorf("openat syscall failed with error: %v", err) + } + case "openat2": + _, err := Openat2Syscall(*step.Args.Dirfd, *step.Args.Filepath, *step.Args.Flags, *step.Args.Mode, *step.Args.Resolve) + if err != nil { + return fmt.Errorf("openat2 syscall failed with error: %v", err) } default: return fmt.Errorf("unsupported syscall: %s", step.Syscall) diff --git a/pkg/declarative/yamltypes.go b/pkg/declarative/yamltypes.go index bb966e8e..09677453 100644 --- a/pkg/declarative/yamltypes.go +++ b/pkg/declarative/yamltypes.go @@ -15,9 +15,17 @@ limitations under the License. package declarative // Yaml file structure +type Args struct { + Dirfd *int `yaml:"dirfd,omitempty"` + Filepath *string `yaml:"filepath,omitempty"` + Flags *int `yaml:"flag,omitempty"` + Mode *uint32 `yaml:"mode,omitempty"` + Resolve *uint64 `yaml:"resolve,omitempty"` +} + type SyscallStep struct { - Syscall string `yaml:"syscall"` - Args map[string]string `yaml:"args"` + Syscall string `yaml:"syscall"` + Args Args `yaml:"args"` } type Test struct { From 785f6690de67dd56f9e3a11f6cca6c2f95184585 Mon Sep 17 00:00:00 2001 From: GLVS Kiriti Date: Thu, 8 Aug 2024 00:33:17 +0530 Subject: [PATCH 2/3] Added symlink link connect socket execve syscall helpers Also added rules is yaml file are triggered Signed-off-by: GLVS Kiriti --- events/exampleyamlfile.yml | 55 +++++++++++++++++++++++++++++++++++- pkg/declarative/helpers.go | 24 ++++++++++++++++ pkg/declarative/host.go | 25 ++++++++++++++++ pkg/declarative/yamltypes.go | 21 ++++++++++++++ 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/events/exampleyamlfile.yml b/events/exampleyamlfile.yml index 04f380c3..56ab213d 100644 --- a/events/exampleyamlfile.yml +++ b/events/exampleyamlfile.yml @@ -7,9 +7,62 @@ tests: args: filepath: "/etc/../etc/../etc/shadow" flag: 0 - mode: 0655 + mode: 0644 + after: "" + + - rule: ReadSensitiveFileUntrusted + runner: HostRunner + before: "" + steps: + - syscall: "open" + args: + filepath: "/etc/shadow" + flag: 0 + mode: 0644 + after: "" + + - rule: ReadSensitiveFileTrustedAfterStartup + runner: HostRunner + before: "" + steps: + - syscall: "open" + args: + filepath: "/etc/shadow" + flag: 0 + mode: 0644 after: "" + - rule: ClearLogActivities + runner: HostRunner + before: "mkdir /tmp/created-by-event-generator && touch /tmp/created-by-event-generator/syslog" + steps: + - syscall: "open" + args: + filepath: "/tmp/created-by-event-generator/syslog" + flag: 513 + mode: 0644 + after: "rm -rf /tmp/created-by-event-generator" + + - rule: CreateSymlinkOverSensitiveFiles + runner: HostRunner + before: "mkdir /created-by-event-generator" + steps: + - syscall: "symlink" + args: + oldpath: "/etc" + newpath: "/created-by-event-generator/newpath" + after: "rm /created-by-event-generator/newpath && rmdir /created-by-event-generator" + + - rule: CreateHardlinkOverSensitiveFiles + runner: HostRunner + before: "mkdir /created-by-event-generator" + steps: + - syscall: "link" + args: + oldpath: "/etc/shadow" + newpath: "/created-by-event-generator/newpath" + after: "rm /created-by-event-generator/newpath && rmdir /created-by-event-generator" + - rule: LaunchIngressRemoteFileCopyToolsInsideContainer runner: ContainerRunner before: "wget example.com" diff --git a/pkg/declarative/helpers.go b/pkg/declarative/helpers.go index 42cbf319..e865e591 100644 --- a/pkg/declarative/helpers.go +++ b/pkg/declarative/helpers.go @@ -88,3 +88,27 @@ func Openat2Syscall(dirfd int, filepath string, flags int, mode uint32, resolve } return fd, nil } + +func ExecveSyscall(exepath string, cmnd []string, envv []string) error { + return unix.Exec(exepath, cmnd, envv) +} + +func ConnectSyscall(sockfd int, socketAddr unix.Sockaddr) error { + return unix.Connect(sockfd, socketAddr) +} + +func SocketSyscall(domain int, socktype int, protocol int) (int, error) { + fd, err := unix.Socket(domain, socktype, protocol) + if err != nil { + return -1, fmt.Errorf("error creating a socket: %v", err) + } + return fd, nil +} + +func SymlinkSyscall(oldpath string, newpath string) error { + return unix.Symlink(oldpath, newpath) +} + +func LinkSyscall(oldpath string, newpath string) error { + return unix.Link(oldpath, newpath) +} diff --git a/pkg/declarative/host.go b/pkg/declarative/host.go index cd8ec914..5ce61b9d 100644 --- a/pkg/declarative/host.go +++ b/pkg/declarative/host.go @@ -50,6 +50,31 @@ func (r *Hostrunner) ExecuteStep(ctx context.Context, test Test) error { if err != nil { return fmt.Errorf("openat2 syscall failed with error: %v", err) } + case "execve": + err := ExecveSyscall(*step.Args.Exepath, *step.Args.Cmnd, *step.Args.Envv) + if err != nil { + return fmt.Errorf("execve syscall failed with error: %v", err) + } + case "connect": + err := ConnectSyscall(*step.Args.Sockfd, *step.Args.Sockaddr) + if err != nil { + return fmt.Errorf("connect syscall failed with error: %v", err) + } + case "socket": + _, err := SocketSyscall(*step.Args.Domain, *step.Args.SockType, *step.Args.Protocol) + if err != nil { + return fmt.Errorf("socket syscall failed with error: %v", err) + } + case "symlink": + err := SymlinkSyscall(*step.Args.Oldpath, *step.Args.Newpath) + if err != nil { + return fmt.Errorf("symlink syscall failed with error: %v", err) + } + case "link": + err := LinkSyscall(*step.Args.Oldpath, *step.Args.Newpath) + if err != nil { + return fmt.Errorf("link syscall failed with error: %v", err) + } default: return fmt.Errorf("unsupported syscall: %s", step.Syscall) } diff --git a/pkg/declarative/yamltypes.go b/pkg/declarative/yamltypes.go index 09677453..7e94a33e 100644 --- a/pkg/declarative/yamltypes.go +++ b/pkg/declarative/yamltypes.go @@ -14,13 +14,34 @@ limitations under the License. package declarative +import "golang.org/x/sys/unix" + // Yaml file structure type Args struct { + // For open, openat, openat2 syscalls Dirfd *int `yaml:"dirfd,omitempty"` Filepath *string `yaml:"filepath,omitempty"` Flags *int `yaml:"flag,omitempty"` Mode *uint32 `yaml:"mode,omitempty"` Resolve *uint64 `yaml:"resolve,omitempty"` + + // For execve syscall + Exepath *string `yaml:"exepath,omitempty"` + Cmnd *[]string `yaml:"cmnd,omitempty"` + Envv *[]string `yaml:"envv,omitempty"` + + // For connect syscall + Sockfd *int `yaml:"sockfd,omitempty"` + Sockaddr *unix.Sockaddr `yaml:"sockaddr,omitempty"` + + // For socket syscall + Domain *int `yaml:"domain,omitempty"` + SockType *int `yaml:"socktype,omitempty"` + Protocol *int `yaml:"protocol,omitempty"` + + // For symlink and link syscalls + Oldpath *string `yaml:"oldpath,omitempty"` + Newpath *string `yaml:"newpath,omitempty"` } type SyscallStep struct { From dae6cc6dee3a00f8e1b9a37537e23dcceee62bbd Mon Sep 17 00:00:00 2001 From: GLVS Kiriti Date: Thu, 8 Aug 2024 17:26:15 +0530 Subject: [PATCH 3/3] Added helpers for sup and ptrace syscalls Signed-off-by: GLVS Kiriti --- pkg/declarative/helpers.go | 12 ++++++++++++ pkg/declarative/host.go | 10 ++++++++++ pkg/declarative/yamltypes.go | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/pkg/declarative/helpers.go b/pkg/declarative/helpers.go index e865e591..59493983 100644 --- a/pkg/declarative/helpers.go +++ b/pkg/declarative/helpers.go @@ -112,3 +112,15 @@ func SymlinkSyscall(oldpath string, newpath string) error { func LinkSyscall(oldpath string, newpath string) error { return unix.Link(oldpath, newpath) } + +func DupSyscall(oldfd int) (int, error) { + newfd, err := unix.Dup(oldfd) + if err != nil { + return -1, err + } + return newfd, nil +} + +func PtraceSyscall(pid int, signal int) error { + return unix.PtraceSyscall(pid, signal) +} diff --git a/pkg/declarative/host.go b/pkg/declarative/host.go index 5ce61b9d..d38f6b65 100644 --- a/pkg/declarative/host.go +++ b/pkg/declarative/host.go @@ -75,6 +75,16 @@ func (r *Hostrunner) ExecuteStep(ctx context.Context, test Test) error { if err != nil { return fmt.Errorf("link syscall failed with error: %v", err) } + case "dup": + _, err := DupSyscall(*step.Args.Oldfd) + if err != nil { + return fmt.Errorf("dup syscall failed with error: %v", err) + } + case "ptrace": + err := PtraceSyscall(*step.Args.Pid, *step.Args.Ptracesignal) + if err != nil { + return fmt.Errorf("ptrace syscall failed with error: %v", err) + } default: return fmt.Errorf("unsupported syscall: %s", step.Syscall) } diff --git a/pkg/declarative/yamltypes.go b/pkg/declarative/yamltypes.go index 7e94a33e..0f1ffed2 100644 --- a/pkg/declarative/yamltypes.go +++ b/pkg/declarative/yamltypes.go @@ -42,6 +42,13 @@ type Args struct { // For symlink and link syscalls Oldpath *string `yaml:"oldpath,omitempty"` Newpath *string `yaml:"newpath,omitempty"` + + // For dup syscall + Oldfd *int `yaml:"oldfd,omitempty"` + + // For ptrace syscall + Pid *int `yaml:"pid,omitempty"` + Ptracesignal *int `yaml:"ptracesignal,omitempty"` } type SyscallStep struct {