Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add helper functions for making syscalls #218

Merged
merged 3 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 54 additions & 10 deletions events/exampleyamlfile.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,68 @@
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"
filepath: "/etc/../etc/../etc/shadow"
flag: 0
mode: 0644
after: ""

- rule: ReadSensitiveFileUntrusted
runner: HostRunner
before: ""
steps:
- syscall: "open"
args:
filepath: "/etc/shadow"
flag: 0
mode: 0644
after: ""

- rule: WriteBelowEtc
- rule: ReadSensitiveFileTrustedAfterStartup
runner: HostRunner
before: ""
steps:
- syscall: "write"
- syscall: "open"
args:
filepath: "/etc/created-by-event-generator"
content: ""
after: "rm -f /etc/created-by-event-generator"
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"
Expand Down
68 changes: 59 additions & 9 deletions pkg/declarative/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,68 @@ 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
}

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

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)
}
52 changes: 49 additions & 3 deletions pkg/declarative/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,55 @@ 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)
}
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)
}
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)
Expand Down
40 changes: 38 additions & 2 deletions pkg/declarative/yamltypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,46 @@ 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"`

// For dup syscall
Oldfd *int `yaml:"oldfd,omitempty"`

// For ptrace syscall
Pid *int `yaml:"pid,omitempty"`
Ptracesignal *int `yaml:"ptracesignal,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 {
Expand Down
Loading