├── .container ├── Dockerfile_Rocky ├── Dockerfile_Ubuntu ├── install-rocky-dependencies.sh └── install-ubuntu-dependencies.sh ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── compliance │ └── inventory.yml └── workflows │ └── scorecard.yml ├── .gitignore ├── .gitmodules ├── BUILD.md ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DEVELOP.md ├── INSTALL.md ├── LICENSE.txt ├── README.md ├── azure-pipelines.yml ├── checkEBPFsizes └── checkEBPFsizes.c ├── diag_script.sh ├── doc ├── 01_introduction_to_eBPF.md ├── 02_tracepoints_etc.md ├── 03_perf_ring_buffer.md ├── 04_reading_memory.md ├── 05_verifier.md ├── 06_networking.md ├── 07_example_programs.md └── examples │ ├── execve_example │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── event_defs.h │ ├── kern.c │ └── user.c │ ├── openat_example │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── event_defs.h │ ├── kern.c │ └── user.c │ └── process_exit_example │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── event_defs.h │ ├── kern.c │ └── user.c ├── ebpfKern ├── HEADER ├── LICENSE ├── makeEvent.sh ├── sysmonCloseFD.c ├── sysmonCloseFD_rawtp.c ├── sysmonCloseFD_tp.c ├── sysmonEBPF_common.h ├── sysmonEBPFkern4.15.c ├── sysmonEBPFkern4.16.c ├── sysmonEBPFkern4.17-5.1.c ├── sysmonEBPFkern5.2.c ├── sysmonEBPFkern5.3-5.5.c ├── sysmonEBPFkern5.6-.c ├── sysmonFileCreate.c ├── sysmonFileCreate_rawtp.c ├── sysmonFileCreate_tp.c ├── sysmonFileDelete.c ├── sysmonFileDeleteAt.c ├── sysmonFileDeleteAtCwd.c ├── sysmonFileDeleteAtCwd_rawtp.c ├── sysmonFileDeleteAtCwd_tp.c ├── sysmonFileDeleteAt_rawtp.c ├── sysmonFileDeleteAt_tp.c ├── sysmonFileDelete_rawtp.c ├── sysmonFileDelete_tp.c ├── sysmonFileOpen.c ├── sysmonFileOpen_rawtp.c ├── sysmonFileOpen_tp.c ├── sysmonGenericEntry_rawtp.c ├── sysmonGenericEntry_tp.c ├── sysmonHelpers.c ├── sysmonProcAccessed.c ├── sysmonProcAccessed_rawtp.c ├── sysmonProcAccessed_tp.c ├── sysmonProcCreate.c ├── sysmonProcCreate_rawtp.c ├── sysmonProcCreate_tp.c ├── sysmonProcTerminated.c ├── sysmonTCPaccept.c ├── sysmonTCPaccept_rawtp.c ├── sysmonTCPaccept_tp.c ├── sysmonTCPconnection_4_15.c ├── sysmonTCPconnection_4_16_5_5.c ├── sysmonTCPconnection_5_6_.c ├── sysmonTEMPLATE.c ├── sysmonTEMPLATE_rawtp.c ├── sysmonTEMPLATE_tp.c ├── sysmonUDPrecv.c ├── sysmonUDPrecv_rawtp.c ├── sysmonUDPrecv_tp.c └── sysmonUDPsend.c ├── extractMsgMc.sh ├── extractMsgOp.sh ├── gnu └── stubs.h ├── hexdump.c ├── hexdump.h ├── installer.c ├── installer.h ├── linuxHelpers.cpp ├── linuxHelpers.h ├── linuxTypes.h ├── linuxVersion.h.in ├── linuxWideChar.c ├── linuxWideChar.h ├── makePackages.sh ├── missingdefs.h ├── networkTracker.cpp ├── networkTracker.h ├── outputxml.c ├── outputxml.h ├── package ├── DEBIAN.in │ └── control.in ├── DEBIAN │ ├── postinst │ ├── postrm │ ├── preinst │ └── prerm ├── SPECS.in │ └── spec.in └── usr │ └── share │ └── man │ └── man8 │ └── sysmon_template.8 ├── perftest ├── README.md ├── TracepointComparisons.md ├── perf.csv ├── perf.png ├── perf2.csv ├── perf2.png ├── perfSysmon.csv ├── sysmonPerf.png └── tests │ ├── audit.rules │ ├── auditbeat.rules │ ├── auditbeat.yml │ ├── auditdenriched.conf │ ├── auditdlaurel.conf │ ├── auditdraw.conf │ ├── execPerSec │ └── execPerSec.c │ ├── go-audit.yaml │ ├── laurel.conf │ ├── onlyProcCreate.xml │ ├── testAuditbeat.sh │ ├── testAuditdNoRules.sh │ ├── testAuditdenriched.sh │ ├── testAuditdraw.sh │ ├── testGoaudit.sh │ ├── testLaurel.sh │ ├── testNoAudit.sh │ └── testSysmon.sh ├── sysmon.d ├── sysmon.gif ├── sysmon.service ├── sysmonLogView ├── README.md ├── sysmonGetEventName.c └── sysmonLogView.cpp ├── sysmon_defs.h ├── sysmonforlinux.c ├── templates └── build.yaml ├── test ├── linuxRules.cpp └── mysleep.c ├── vmlinux.h └── vmlinux_kern_diffs.h /.container/Dockerfile_Rocky: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/mirror/docker/library/rockylinux:8 2 | 3 | # Install dependencies 4 | COPY install-rocky-dependencies.sh /usr/local/bin/install_dependencies.sh 5 | RUN chmod +x /usr/local/bin/install_dependencies.sh && \ 6 | /usr/local/bin/install_dependencies.sh -------------------------------------------------------------------------------- /.container/Dockerfile_Ubuntu: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/mirror/docker/library/ubuntu:20.04 2 | 3 | # Install dependencies 4 | COPY install-ubuntu-dependencies.sh /usr/local/bin/install_dependencies.sh 5 | RUN chmod +x /usr/local/bin/install_dependencies.sh && \ 6 | /usr/local/bin/install_dependencies.sh -------------------------------------------------------------------------------- /.container/install-rocky-dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # install all needed packges to build .rpm packages 4 | echo "assumeyes=1" >> sudo /etc/yum.conf 5 | 6 | # install endpoint for git > 2.0 7 | sudo yum install http://opensource.wandisco.com/rhel/8/git/x86_64/wandisco-git-release-8-1.noarch.rpm 8 | 9 | # Enable powertools and extra repos 10 | sudo dnf install dnf-plugins-core && sudo dnf install epel-release && sudo dnf config-manager --set-enabled powertools && sudo dnf update 11 | 12 | sudo yum install \ 13 | git \ 14 | gcc \ 15 | gcc-c++ \ 16 | make \ 17 | cmake \ 18 | llvm \ 19 | clang \ 20 | elfutils-libelf-devel \ 21 | rpm-build \ 22 | json-glib-devel \ 23 | python3 \ 24 | libxml2-devel \ 25 | glibc-devel.i686 \ 26 | gtest-devel \ 27 | gmock \ 28 | gmock-devel \ 29 | which \ 30 | wget \ 31 | redhat-lsb \ 32 | clang-analyzer \ 33 | openssl-devel 34 | 35 | # Remove old pip and setuptools versions due to security issues 36 | sudo pip3 uninstall -y setuptools 37 | sudo pip3 uninstall -y pip 38 | 39 | # install JQ since it doesn't have a .rpm package 40 | curl https://stedolan.github.io/jq/download/linux64/jq > sudo /usr/bin/jq && sudo chmod +x /usr/bin/jq 41 | 42 | #install .NET and T4 text transform 43 | sudo dnf install dotnet-sdk-6.0 44 | dotnet tool install --global dotnet-t4 --version 2.3.1 -------------------------------------------------------------------------------- /.container/install-ubuntu-dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # To make it easier for build and release pipelines to run apt-get, 4 | # configure apt to not require confirmation (assume the -y argument by default) 5 | DEBIAN_FRONTEND=noninteractive 6 | 7 | sudo apt-get update && sudo apt-get install -y gnupg wget 8 | 9 | #install .NET and T4 text transform 10 | apt install -y dotnet-sdk-8.0 11 | dotnet tool install --global dotnet-t4 --version 2.3.1 12 | 13 | sudo apt-get install -y --no-install-recommends \ 14 | curl \ 15 | git \ 16 | build-essential \ 17 | gcc \ 18 | g++ \ 19 | make \ 20 | cmake \ 21 | libelf-dev \ 22 | llvm \ 23 | clang \ 24 | libxml2 \ 25 | libxml2-dev \ 26 | libzstd1 \ 27 | libgtest-dev \ 28 | libc6-dev-i386 \ 29 | apt-transport-https \ 30 | dirmngr \ 31 | googletest \ 32 | google-mock \ 33 | libgmock-dev \ 34 | libjson-glib-dev \ 35 | liblocale-gettext-perl \ 36 | ca-certificates \ 37 | fakeroot \ 38 | lsb-release \ 39 | software-properties-common \ 40 | gettext \ 41 | pax \ 42 | clang-tools \ 43 | libssl-dev 44 | 45 | sudo wget https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/openat2.h -O /usr/include/linux/openat2.h 46 | 47 | # install debbuild 48 | wget https://github.com/debbuild/debbuild/releases/download/22.02.1/debbuild_22.02.1-0ubuntu20.04_all.deb \ 49 | && sudo dpkg -i debbuild_22.02.1-0ubuntu20.04_all.deb 50 | 51 | PATH="$PATH:/root/.dotnet/tools" 52 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: MarioHewardt 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. 15 | 16 | **Sysmon version** 17 | Version of Sysmon or if built from source. 18 | 19 | **Distro/kernel version** 20 | The distribution and kernel version. 21 | 22 | **Sysmon configuration** 23 | The Sysmon configuration when the issue occurred. 24 | 25 | **Logs** 26 | Output of syslog with enough log entries to cover the timespan of the issue. Please run sysmon with the -t switch 27 | 28 | **Expected behavior** 29 | A clear and concise description of what you expected to happen. 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/compliance/inventory.yml: -------------------------------------------------------------------------------- 1 | inventory: 2 | - source: DirectOwners 3 | isProduction: false 4 | items: 5 | - id: marioh@microsoft.com 6 | -------------------------------------------------------------------------------- /.github/workflows/scorecard.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. They are provided 2 | # by a third-party and are governed by separate terms of service, privacy 3 | # policy, and support documentation. 4 | 5 | name: Scorecard supply-chain security 6 | on: 7 | # For Branch-Protection check. Only the default branch is supported. See 8 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection 9 | branch_protection_rule: 10 | # To guarantee Maintained check is occasionally updated. See 11 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained 12 | schedule: 13 | - cron: '39 2 * * 6' 14 | push: 15 | branches: [ "main" ] 16 | 17 | # Declare default permissions as read only. 18 | permissions: read-all 19 | 20 | jobs: 21 | analysis: 22 | name: Scorecard analysis 23 | runs-on: ubuntu-latest 24 | permissions: 25 | # Needed to upload the results to code-scanning dashboard. 26 | security-events: write 27 | # Needed to publish results and get a badge (see publish_results below). 28 | id-token: write 29 | # Uncomment the permissions below if installing in a private repository. 30 | # contents: read 31 | # actions: read 32 | 33 | steps: 34 | - name: "Checkout code" 35 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 36 | with: 37 | persist-credentials: false 38 | 39 | - name: "Run analysis" 40 | uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 41 | with: 42 | results_file: results.sarif 43 | results_format: sarif 44 | # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: 45 | # - you want to enable the Branch-Protection check on a *public* repository, or 46 | # - you are installing Scorecard on a *private* repository 47 | # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. 48 | # repo_token: ${{ secrets.SCORECARD_TOKEN }} 49 | 50 | # Public repositories: 51 | # - Publish results to OpenSSF REST API for easy access by consumers 52 | # - Allows the repository to include the Scorecard badge. 53 | # - See https://github.com/ossf/scorecard-action#publishing-results. 54 | # For private repositories: 55 | # - `publish_results` will always be set to `false`, regardless 56 | # of the value entered here. 57 | publish_results: true 58 | 59 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF 60 | # format to the repository Actions tab. 61 | - name: "Upload artifact" 62 | uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20 63 | with: 64 | name: SARIF file 65 | path: results.sarif 66 | retention-days: 5 67 | 68 | # Upload the results to GitHub's code scanning dashboard (optional). 69 | # Commenting out will disable upload of results to your repo's Code Scanning dashboard 70 | - name: "Upload to code-scanning" 71 | uses: github/codeql-action/upload-sarif@v3 72 | with: 73 | sarif_file: results.sarif 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Logs 35 | *.log 36 | *.db 37 | 38 | # CMake 39 | CMakeLists.txt.user 40 | CMakeCache.txt 41 | CMakeFiles 42 | CMakeScripts 43 | Testing 44 | Makefile 45 | cmake_install.cmake 46 | install_manifest.txt 47 | compile_commands.json 48 | CTestTestfile.cmake 49 | 50 | # build artifacts 51 | bin/ 52 | build/ 53 | obj/ 54 | pkgbuild/ 55 | 56 | # dev env 57 | .vscode/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sysmonCommon"] 2 | path = sysmonCommon 3 | url = https://github.com/Microsoft/SysmonCommon.git 4 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # Build 2 | Please see the history of this file for instructions for older, unsupported versions. 3 | 4 | ## Prerequisites 5 | - SysinternalsEBPF being installed: 6 | library `libsysinternalsEBPF.so`, header `libsysinternalsEBPF.h`, plus 7 | resource files in `/opt/sysinternalsEBPF`. These can be installed from 8 | the 9 | [SysinternalsEBPF](https://github.com/Microsoft/SysinternalsEBPF) 10 | project or via the `sysinternalsebpf` DEB package from the 11 | _packages.microsoft.com_ repository (see [INSTALL.md](INSTALL.md)). 12 | If you installed SysinternalsEBPF via make install, you may need to add /usr/local/lib to the loader library path (LD_LIBRARY_PATH). 13 | 14 | - .NET SDK. Please see [.NET Installation](https://learn.microsoft.com/en-us/dotnet/core/install/linux). Note: If during installation you encounter "A fatal error occurred. The folder [/usr/share/dotnet/host/fxr] does not exist", please see [here](https://stackoverflow.com/questions/73753672/a-fatal-error-occurred-the-folder-usr-share-dotnet-host-fxr-does-not-exist) 15 | 16 | - clang/llvm v10+ 17 | 18 | ### Azure Linux 19 | ``` 20 | sudo dnf update 21 | dotnet tool install --global dotnet-t4 --version 2.3.1 22 | sudo dnf install gcc gcc-c++ make cmake llvm clang elfutils-libelf-devel rpm-build json-glib-devel python3 libxml2-devel gtest-devel gmock gmock-devel openssl-devel perl 23 | ``` 24 | 25 | ### Ubuntu 20.04+ 26 | ``` 27 | sudo apt update 28 | dotnet tool install --global dotnet-t4 --version 2.3.1 29 | sudo apt -y install build-essential gcc g++ make cmake libelf-dev llvm clang libxml2 libxml2-dev libzstd1 git libgtest-dev apt-transport-https dirmngr googletest google-mock libgmock-dev libjson-glib-dev libssl-dev 30 | ``` 31 | 32 | ### Rocky 9 33 | ``` 34 | sudo dnf install dnf-plugins-core 35 | sudo dnf config-manager --set-enabled crb 36 | sudo dnf install epel-release 37 | 38 | sudo dnf update 39 | dotnet tool install --global dotnet-t4 --version 2.3.1 40 | sudo yum install gcc gcc-c++ make cmake llvm clang elfutils-libelf-devel rpm-build json-glib-devel python3 libxml2-devel gtest-devel gmock gmock-devel openssl-devel 41 | ``` 42 | 43 | ### Rocky 8 44 | ``` 45 | sudo dnf install dnf-plugins-core 46 | sudo dnf install epel-release 47 | sudo dnf config-manager --set-enabled powertools 48 | 49 | sudo dnf update 50 | dotnet tool install --global dotnet-t4 --version 2.3.1 51 | sudo yum install gcc gcc-c++ make cmake llvm clang elfutils-libelf-devel rpm-build json-glib-devel python3 libxml2-devel gtest-devel gmock gmock-devel openssl-devel 52 | ``` 53 | 54 | ### Debian 11 55 | ``` 56 | wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb 57 | sudo dpkg -i packages-microsoft-prod.deb 58 | rm packages-microsoft-prod.deb 59 | sudo apt update 60 | dotnet tool install --global dotnet-t4 --version 2.3.1 61 | sudo apt -y install build-essential gcc g++ make cmake libelf-dev llvm clang libzstd1 git libjson-glib-dev libxml2 libxml2-dev googletest google-mock libgmock-dev libssl-dev 62 | ``` 63 | 64 | ## Build 65 | ``` 66 | cd 67 | git clone --recurse-submodules https://github.com/Microsoft/SysmonForLinux.git 68 | cd SysmonForLinux 69 | mkdir build 70 | cd build 71 | cmake .. 72 | make 73 | ``` 74 | 75 | ## Test 76 | ``` 77 | ./sysmonUnitTests 78 | ``` 79 | 80 | ## Run 81 | ``` 82 | sudo ./sysmon -? 83 | ``` 84 | 85 | ## Install 86 | ``` 87 | sudo ./sysmon -i CONFIG_FILE 88 | ``` 89 | This will install sysmon and associated files into the /opt/sysmon directory. 90 | The binary is portable and self-contained - the build process packs the 91 | required files into the binary for installation with '-i'. Sysmon will restart 92 | on reboot with the same configuration. 93 | 94 | Change the configuration with 95 | ``` 96 | sudo /opt/sysmon/sysmon -c CONFIG_FILE 97 | ``` 98 | 99 | Uninstall sysmon with 100 | ``` 101 | sudo /opt/sysmon/sysmon -u 102 | ``` 103 | 104 | ## Make Packages 105 | Packages can be generated with: 106 | ``` 107 | make deb 108 | ``` 109 | or 110 | ``` 111 | make rpm 112 | ``` 113 | 114 | The directories build/deb and build/rpm will be populated with the required 115 | files. If dpkg-deb is available, the build/deb directory will be used to create 116 | a deb package. Similarly if rpmbuild is available, the build/rpm directory will 117 | be used to create an rpm package. 118 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Before we can accept a pull request from you, you'll need to sign a [Contributor License Agreement (CLA)](https://cla.microsoft.com). It is an automated process and you only need to do it once. 4 | To enable us to quickly review and accept your pull requests, always create one pull request per issue and link the issue in the pull request. Never merge multiple requests in one unless they have the same root cause. Be sure to follow our Coding Guidelines and keep code changes as small as possible. Avoid pure formatting changes to code that has not been modified otherwise. Pull requests should contain tests whenever possible. 5 | 6 | # Branching 7 | The master branch contains current development. While CI should ensure that master always builds, it is still considered pre-release code. Release checkpoints will be put into stable branches for maintenance. 8 | 9 | To contribute, fork the repository and create a branch in your fork for your work. Please keep branch names short and descriptive. Please direct PRs into the upstream master branch. 10 | 11 | # Testing 12 | * There are a multitude of tests included in the `tests` directory of the repository. 13 | * Add new tests corresponding to your change, if applicable. Include tests when adding new features. When fixing bugs, start with adding a test that highlights how the current behavior is broken. 14 | * Make sure that the tests are all passing, including your new tests. 15 | 16 | # Pull Requests 17 | * Always tag a work item or issue with a pull request. 18 | * Limit pull requests to as few issues as possible, preferably 1 per PR 19 | 20 | 21 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Install Sysmon 2 | Please see the history of this file for instructions for older, unsupported versions. 3 | 4 | ## Azure Linux 3 5 | ```sh 6 | sudo dnf install sysmonforlinux 7 | ``` 8 | 9 | ## Ubuntu 10 | #### 1. Register Microsoft key and feed 11 | ```sh 12 | wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb 13 | sudo dpkg -i packages-microsoft-prod.deb 14 | ``` 15 | 16 | #### 2. Install sysmonforlinux 17 | ```sh 18 | sudo apt-get update 19 | sudo apt-get install sysmonforlinux 20 | ``` 21 | 22 | ## Debian 23 | #### 1. Register Microsoft key and feed 24 | ```sh 25 | wget -q https://packages.microsoft.com/config/debian/$(. /etc/os-release && echo ${VERSION_ID%%.*})/packages-microsoft-prod.deb -O packages-microsoft-prod.deb 26 | sudo dpkg -i packages-microsoft-prod.deb 27 | ``` 28 | 29 | #### 2. Install sysmonforlinux 30 | ```sh 31 | sudo apt-get update 32 | sudo apt-get install sysmonforlinux 33 | ``` 34 | 35 | ## Fedora 36 | #### 1. Register Microsoft key and feed 37 | ```sh 38 | sudo rpm -Uvh https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/packages-microsoft-prod.rpm 39 | ``` 40 | 41 | #### 2. Install sysmonforlinux 42 | ```sh 43 | sudo apt-get update 44 | sudo apt-get install sysmonforlinux 45 | ``` 46 | 47 | ## RHEL 48 | #### 1. Register Microsoft key and feed 49 | ```sh 50 | sudo rpm -Uvh https://packages.microsoft.com/config/rhel/$(. /etc/os-release && echo ${VERSION_ID%%.*})/packages-microsoft-prod.rpm 51 | ``` 52 | 53 | #### 2. Install sysmonforlinux 54 | ```sh 55 | sudo yum install sysmonforlinux 56 | ``` 57 | 58 | ## openSUSE 15 59 | #### 1. Register Microsoft key and feed 60 | ```sh 61 | sudo zypper install libicu 62 | sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc 63 | wget -q https://packages.microsoft.com/config/opensuse/15/prod.repo 64 | sudo mv prod.repo /etc/zypp/repos.d/microsoft-prod.repo 65 | sudo chown root:root /etc/zypp/repos.d/microsoft-prod.repo 66 | ``` 67 | 68 | #### 2. Install SysmonForLinux 69 | ```sh 70 | sudo zypper install sysmonforlinux 71 | ``` 72 | 73 | ## SLES 15 74 | #### 1. Register Microsoft key and feed 75 | ```sh 76 | sudo rpm -Uvh https://packages.microsoft.com/config/sles/15/packages-microsoft-prod.rpm 77 | ``` 78 | 79 | #### 2. Install SysmonForLinux 80 | ```sh 81 | sudo zypper install sysmonforlinux 82 | ``` 83 | 84 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://dev.azure.com/sysinternals/Tools/_apis/build/status/Sysinternals.SysmonForLinux?repoName=Sysinternals%2FSysmonForLinux&branchName=main)](https://dev.azure.com/sysinternals/Tools/_build/latest?definitionId=340&repoName=Sysinternals%2FSysmonForLinux&branchName=main) 2 | 3 | # Sysmon for Linux 4 | Sysmon for Linux is a tool that monitors and logs system activity including process lifetime, network connections, file system writes, and more. Sysmon works across reboots and uses advanced filtering to help identify malicious activity as well as how intruders and malware operate on your network. 5 | Sysmon for Linux is part of [Sysinternals](https://sysinternals.com). 6 | 7 | ![Sysmon in use](sysmon.gif "Sysmon in use") 8 | 9 | ## Installation 10 | The packages are available in the official Microsoft Linux repositories and instructions on how to install the packages for the different Linux distributions can be found in the [Installation instructions](INSTALL.md). 11 | 12 | This project contains the code for build and installing [Sysmon](https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon) on Linux. 13 | 14 | ## Build 15 | Please see build instructions [here](BUILD.md). 16 | 17 | ## Autodiscovery of Offsets 18 | On systems that are BTF enabled, Sysmon will use BTF for accurate kernel offsets. 19 | Sysmon also supports specifying standalone BTF files (using /BTF switch). There are 20 | several ways to generate BTF files and [BTFHub](https://github.com/aquasecurity/btfhub) 21 | has a number of standalone BTF files for different distributions/kernels. 22 | 23 | If BTF isn't available, Sysmon attempts to automatically discover the offsets of some 24 | members of some kernel structs. If this fails, please provide details of the kernel 25 | version (and config if possible) plus the error message to the GitHub issues page. 26 | 27 | You can then generate a configuration file to override the autodiscovery by 28 | building the getOffsets module in the /opt/sysinternals/getOffsets directory. 29 | See the README.md in that directory for more information. 30 | 31 | ## Manual Page 32 | A man page for Sysmon can be found in the package directory, and is installed 33 | by both deb and rpm packages. 34 | 35 | Use 'find' on the package directory to locate it manually. 36 | 37 | ## Output 38 | ``` 39 | sudo tail -f /var/log/syslog 40 | ``` 41 | or more human-readable 42 | ``` 43 | sudo tail -f /var/log/syslog | sudo /opt/sysmon/sysmonLogView 44 | ``` 45 | 46 | SysmonLogView has options to filter the output to make it easy to identify 47 | specific events or reduce outputted fields for brevity. 48 | 49 | SysmonLogView is built when Sysmon is built and is installed into /opt/sysmon 50 | when sysmon is installed. 51 | 52 | *Important*: You may wish to modify your Syslogger config to ensure it can 53 | handle particularly large events (e.g. >64KB, as defaults are often between 1KB 54 | and 8KB), and/or use the FieldSizes configuration entry to limit the length of 55 | output for some fields, such as CommandLine, Image, CurrentDirectory, etc. 56 | 57 | Example: 58 | 59 | Add \CommandLine:100,Image:20\ under 60 | \ in your configuration file. 61 | 62 | ## Developer Details 63 | See DEVELOP.md 64 | 65 | ## License 66 | Sysmon For Linux is licensed under MIT, with the eBPF programs licensed under 67 | GPL2. SysinternalsEBPF (on which Sysmon For Linux depends) is licensed under 68 | LGPL2.1, with the eBPF code library licensed under GPL2. 69 | 70 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Azure build pipelines for Sysmon 2 | 3 | resources: 4 | repositories: 5 | - repository: Sysmon 6 | type: github 7 | endpoint: sysinternals 8 | name: Microsoft/SysmonForLinux 9 | 10 | - repository: SysinternalsEBPF 11 | type: github 12 | endpoint: sysinternals 13 | name: Microsoft/SysinternalsEBPF 14 | 15 | trigger: 16 | branches: 17 | include: 18 | - release/* 19 | - main 20 | exclude: 21 | - dev/* 22 | - test/* 23 | 24 | pr: 25 | - main 26 | 27 | stages: 28 | - stage: "Build" 29 | jobs: 30 | - job: "Build_Sysmon_Ubuntu" 31 | pool: 32 | vmImage: "ubuntu-22.04" 33 | timeoutInMinutes: 240 34 | steps: 35 | - checkout: self 36 | submodules: true 37 | 38 | - checkout: SysinternalsEBPF 39 | 40 | - script: | 41 | chmod +x SysmonForLinux/.container/install-ubuntu-dependencies.sh 42 | SysmonForLinux/.container/install-ubuntu-dependencies.sh 43 | displayName: "Install pre-reqs for Ubuntu" 44 | 45 | - template: templates/build.yaml@SysinternalsEBPF 46 | parameters: 47 | srcPath: 'SysinternalsEBPF' 48 | runStaticAnalysis: false 49 | builddir: 'sysinternalsEBPF_build' 50 | 51 | - script: | 52 | cd $(Build.SourcesDirectory)/SysinternalsEBPF/sysinternalsEBPF_build 53 | sudo make install 54 | sudo ldconfig 55 | displayName: "Install SysinternalsEBPF" 56 | 57 | - template: templates/build.yaml 58 | parameters: 59 | srcPath: 'SysmonForLinux' 60 | runStaticAnalysis: true 61 | builddir: 'sysmon_build' 62 | -------------------------------------------------------------------------------- /checkEBPFsizes/checkEBPFsizes.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // checkEBPFsizes.c 20 | // 21 | // Checks the eBPF program lengths against a user-supplied max number 22 | // of instructions. 23 | // 24 | //==================================================================== 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | int maxInsns = 0; 45 | unsigned int numProgs = 0; 46 | bool fail = false; 47 | ebpfProgramSizes* progs = NULL; 48 | 49 | 50 | if (argc < 3) { 51 | printf("Usage: %s \n", argv[0]); 52 | return 1; 53 | } 54 | 55 | maxInsns = atoi(argv[2]); 56 | if (maxInsns <= 0) { 57 | printf("%s: maximum instructions must be greater than 0\n", argv[0]); 58 | return 1; 59 | } 60 | 61 | numProgs = getEbpfProgramSizes(argv[1], &progs); 62 | if(numProgs>0) 63 | { 64 | for(int i=0; i maxInsns) 67 | { 68 | printf(" Error: %s is greater than max instructions: %d > %d\n", progs[i].name, (int)progs[i].size, maxInsns); 69 | fail = true; 70 | } 71 | } 72 | 73 | free(progs); 74 | } 75 | 76 | printf("\n"); 77 | 78 | if (fail) 79 | return 2; 80 | 81 | return 0; 82 | } 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /diag_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | process_name="t4" 3 | 4 | # Wait enough time for it to get into hung state 5 | sleep 20m 6 | counter=1 7 | while [ $counter -le 20 ] 8 | do 9 | if pgrep -x "$process_name" > /dev/null; then 10 | echo "Process $process_name is running. Dumping stacks..." 11 | process_id=$(pgrep -x "$process_name") 12 | $HOME/.dotnet/tools/dotnet-stack report -p "$process_id" 13 | echo "Stacks dumped" 14 | fi 15 | 16 | sleep 1m 17 | counter=$((counter + 1)) 18 | done -------------------------------------------------------------------------------- /doc/04_reading_memory.md: -------------------------------------------------------------------------------- 1 | # Reading Memory 2 | 3 | ## Introduction 4 | 5 | As eBPF is a safe language, it will only allow you to read memory that you 6 | either own yourself, or has been accessed correctly via a helper. This chapter 7 | discusses how to access memory correctly and the issues with it. 8 | 9 | ## Memory you own 10 | 11 | You own the following memory and therefore can read it without issue: 12 | 13 | * Parameters passed to eBPF programs; 14 | * Local eBPF stack variables; 15 | * Retrieved entries from maps; 16 | 17 | You can dereference and read this memory directly, with the usual C language 18 | instructions, including memcpy(), which is usually inlined by the compiler for 19 | you. If memcpy() is prohibited by the verifier, you can swap it with 20 | bpf\_probe\_read(). Take care as the parameters are in a different order. 21 | 22 | ## Memory accessed via a helper 23 | 24 | All other memory access must go via a helper, such as bpf\_probe\_read() and 25 | bpf\_probe\_read\_str(). These helpers must be used to dereference and read 26 | memory from the task\_struct, any structs linked from it, and any userland 27 | memory. 28 | 29 | ## Issues 30 | 31 | The only real issue with reading memory is that, usually, eBPF programs cannot 32 | 'sleep', which means they cannot access memory that is paged out. 33 | 34 | Memory is paged in when it is required, and is paged out when it hasn't been 35 | accessed for a while and another chunk of memory needs its slot. Outside of 36 | eBPF, when a program attempts to access paged-out memory, an interrupt occurs 37 | handing control temporarily to the interrupt handler in the kernel. This 38 | pages-in the required memory chunk, then resets the program counter back to the 39 | faulting instruction, and returns from the interrupt handler. 40 | 41 | This process happens automatically in non-eBPF situations; memory appears to be 42 | seamlessly paged in as it is required and programs are largely unaware of it 43 | happening (although timing could probably be used to identify it). 44 | 45 | eBPF programs usually cannot sleep. This means that interrupts are suspended 46 | when they run, preventing the above process from happening. Instead, when an 47 | eBPF program attempts to access paged-out memory via a helper, the call to the 48 | helper fails with an error code, and the destination buffer is zeroed. 49 | 50 | ## Avoiding paged-out memory 51 | 52 | The way to avoid the situation is to only read memory after it has recently 53 | been accessed, causing the likelihood of it being paged-in to be high. For 54 | syscall tracepoints, this can be achieved by only reading memory in programs 55 | attached to the exit tracepoints. The logic is that the kernel will have 56 | accessed the memory that you are interested in, just prior to you attempting 57 | access. 58 | 59 | With non-syscall tracepoints, there is no enter and exit, just the tracepoint. 60 | But often there are multiple tracepoints in the same event class or related 61 | events in other classes that occur in the same execution path. By exploring 62 | these it may be possible to find an event that occurs after the desired memory 63 | has been accessed by the kernel. It may be necessary to combine information 64 | from different tracepoints, accessing some information in one tracepoint and 65 | other information in another. 66 | -------------------------------------------------------------------------------- /doc/07_example_programs.md: -------------------------------------------------------------------------------- 1 | # Example Programs 2 | 3 | ## Introduction 4 | 5 | This chapter describes the three example programs in the examples folder. 6 | 7 | ## Generic program structure 8 | 9 | The kern.c file contains the eBPF code that will be loaded into the kernel, and 10 | the user.c file is its loader and controller. event\_defs.h is shared between 11 | both of them, and specifies the structs that are passed between the eBPF part 12 | and the userland part. 13 | 14 | ### eBPF part 15 | 16 | The typical layout of the eBPF part consists of the following: 17 | 18 | * includes 19 | * defines 20 | * maps - for perf ring buffer and any data structures 21 | * structs for tracepoint arguments 22 | * tracepoint programs 23 | 24 | ### Userland part 25 | 26 | The typical layout of the userland part consists of the following: 27 | 28 | * includes 29 | * globals - bpf FDs, objects, programs and links 30 | * bpf\_close\_all() - destroys the links 31 | * print\_bpf\_output() - receives eBPF events from perf ring buffer 32 | * handle\_lost\_events() - handles lost events 33 | * intHandler() - handles ^C 34 | * main() - sets up the eBPF: 35 | - setrlimit() - remove memory limitations 36 | - bpf\_object\_\_open() - access the eBPF ELF object 37 | - bpf\_object\_\_find\_program\_by\_title() - located program by ELF section 38 | - bpf\_object\_\_set\_type() - set the type of program; typically 39 | BPF\_PROG\_TYPE\_TRACEPOINT or BPF\_PROG\_TYPE\_RAW\_TRACEPOINT 40 | - bpf\_object\_\_load() - load eBPF programs into memory 41 | - bpf\_object\_\_find\_map\_fd\_by\_name() - locate map file descriptors 42 | - bpf\_program\_\_attach\_tracepoint() / 43 | bpf\_program\_\_attach\_raw\_tracepoint() - attach the programs to tracepoints 44 | - perf\_buffer\_\_new() - create a new perf buffer with event (sample) 45 | handling callbacks 46 | 47 | ## openat example 48 | 49 | This example demonstrates how to attach to traditional syscall tracepoints, the 50 | overall syscall architecture tracepoints, and the overall syscall architecture 51 | as raw tracepoints. All three do the same thing and can be selected at run time 52 | by specifying 1, 2, or 3 on the command line. 53 | 54 | The first type attaches to syscalls/sys\_enter\_openat and 55 | syscalls/sys\_exit\_openat. These are tracepoints specifically for the openat 56 | syscall and can only be attached to as traditional tracepoints (not raw). The 57 | enter program receives arguments specific to the openat syscall. 58 | 59 | The second type attaches to raw\_syscalls/sys\_enter and 60 | raw\_syscalls/sys\_exit. These tracepoints are on the entry and exit of the 61 | entire syscall architecture so every syscall will hit them. The arguments to 62 | sys\_enter are generically a syscall ID and an array of six uint64\_t. 63 | 64 | The third type attaches to the same as the second, but as raw tracepoints, 65 | which should be faster. The arguments are the CPU registers and the syscall ID. 66 | 67 | Each of the enter programs stores the arguments; and each of the exit programs 68 | reads the filename and creates an event. As much of the work is the same, the 69 | exit programs call a shared inline function to do the work. 70 | 71 | ## execve example 72 | 73 | This example demonstrates the various ways of attaching to tracepoints related 74 | to process creation. Different tracepoints provide different information, but 75 | typically (without access to kernel internals such as task\_struct) the 'exec' 76 | tracepoints get the program being executed and the PID, and the 'fork' 77 | tracepoints get the same plus the parent PID. These could be associated in 78 | userland if required. 79 | 80 | Rather than specify which type to attach to on the command line, this program 81 | attaches to all at once and distinguishes them in the event struct and program 82 | output. Many of them share the write\_event() inline function to build and 83 | dispatch the event. 84 | 85 | It is worth noting that task/task\_newtask receives the clone\_flags as part of 86 | its arguments, which can distinguish between fork() (new process) and clone() 87 | (new thread). 88 | 89 | ## process\_exit example 90 | 91 | This example demonstrates how to attach to the same tracepoint as either 92 | traditional or raw. The execve tracepoints were not very useful as raw 93 | tracepoints because the raw arguments didn't provide much information; a 94 | program would have to navigate the task\_struct to find the details. The 95 | sched/process\_exit tracepoint, however, only receives useful information as 96 | arguments that can also be obtained through helpers, namely the PID and the 97 | comm. 98 | 99 | -------------------------------------------------------------------------------- /doc/examples/execve_example/README.md: -------------------------------------------------------------------------------- 1 | # eBPF execve example 2 | 3 | This small EBPF program demonstrates how to build a simple tracepoint 4 | program outside of the kernel tree, that doesn't rely on kernel sources. 5 | 6 | Specifically, it shows the different tracepoints related to process start. 7 | 8 | It builds and runs on kernel v4.15 and above. 9 | 10 | * mkdir build 11 | * cd build 12 | * cmake .. 13 | * make 14 | * sudo ./user 15 | 16 | Needs cmake>=3.10, clang, llvm and libelf-dev. It fetches its own copy of 17 | libbpf from github as part of configure and build. 18 | 19 | 20 | -------------------------------------------------------------------------------- /doc/examples/execve_example/event_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | eBPF execve example 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #ifndef EVENT_DEFS_H 24 | #define EVENT_DEFS_H 25 | 26 | #include 27 | 28 | // Event structure 29 | typedef struct { 30 | pid_t pid; 31 | pid_t ppid; 32 | int size; 33 | int type; 34 | char exe[4096]; 35 | } event_s; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /doc/examples/openat_example/README.md: -------------------------------------------------------------------------------- 1 | # eBPF openat example 2 | 3 | This small eBPF program demonstrates how to build a simple tracepoint 4 | program outside of the kernel tree, that doesn't rely on kernel sources. 5 | 6 | Specifically, it shows how to connect to syscall tracepoints. 7 | 8 | It builds and runs on kernel v4.15 and above. 9 | 10 | * mkdir build 11 | * cd build 12 | * cmake .. 13 | * make 14 | * sudo ./user 15 | 16 | Needs cmake>=3.10, clang, llvm and libelf-dev. It fetches its own copy of 17 | libbpf from github as part of configure and build. 18 | 19 | The user program takes a single argument to specify which version of eBPF 20 | code to run: 21 | 22 | * 1 = tracepoints syscalls/sys\_openat\_enter / exit 23 | * 2 = tracepoints raw\_syscalls/sys\_enter / exit 24 | * 3 = raw tracepoints raw\_syscalls/sys\_enter / exit 25 | 26 | Each version does the same thing - reports the filepath, flags and mode of 27 | files successfully opened with the openat() syscall. The first connects 28 | directly to the openat enter and exit (traditional tracepoints); the second 29 | connects to the enter and exit for the syscall architecture (traditional 30 | tracepoints again); and the third connects to the raw tracepoints at the 31 | enter and exit of the syscall architecture. It is not possible to connect 32 | to the openat syscall enter and exit as raw tracepoints. 33 | 34 | -------------------------------------------------------------------------------- /doc/examples/openat_example/event_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | eBPF openat example 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #ifndef EVENT_DEFS_H 24 | #define EVENT_DEFS_H 25 | 26 | #include 27 | 28 | // Event structure 29 | typedef struct { 30 | pid_t pid; 31 | uint64_t flags; 32 | uint64_t mode; 33 | char filename[4096]; 34 | } event_s; 35 | 36 | // Event args structure 37 | typedef struct { 38 | uint32_t syscall; 39 | uint64_t args[6]; 40 | } event_args_s; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /doc/examples/process_exit_example/README.md: -------------------------------------------------------------------------------- 1 | # eBPF process\_exit example 2 | 3 | This small eBPF program demonstrates how to build a simple tracepoint 4 | program outside of the kernel tree, that doesn't rely on kernel sources. 5 | 6 | Specifically, it demonstrates how to attach to the same tracepoint as 7 | normal and as a raw tracepoint (which should be faster). 8 | 9 | It builds and runs on kernel v4.15 and above. 10 | 11 | * mkdir build 12 | * cd build 13 | * cmake .. 14 | * make 15 | * sudo ./user 16 | 17 | Needs cmake>=3.10, clang, llvm and libelf-dev. It fetches its own copy of 18 | libbpf from github as part of configure and build. 19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/examples/process_exit_example/event_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | eBPF process_exit example 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #ifndef EVENT_DEFS_H 24 | #define EVENT_DEFS_H 25 | 26 | #include 27 | 28 | // Event structure 29 | typedef struct { 30 | pid_t pid; 31 | int size; 32 | int type; 33 | char exe[4096]; 34 | } event_s; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /doc/examples/process_exit_example/kern.c: -------------------------------------------------------------------------------- 1 | /* 2 | eBPF process_exit example 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "event_defs.h" 36 | 37 | #define BPF_F_INDEX_MASK 0xffffffffULL 38 | #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK 39 | 40 | // debug tracing can be found using: 41 | // #cat /sys/kernel/debug/tracing/trace_pipe 42 | 43 | #ifdef DEBUG_K 44 | #define BPF_PRINTK( format, ... ) \ 45 | char fmt[] = format; \ 46 | bpf_trace_printk(fmt, sizeof(fmt), ##__VA_ARGS__ ); 47 | #else 48 | #define BPF_PRINTK ((void)0); 49 | #endif 50 | 51 | // missing stddef.h defines 52 | #define NULL ((void *)0) 53 | typedef int bool; 54 | #define true 1 55 | #define false 0 56 | 57 | // missing PT_REGS defines 58 | #define PT_REGS_PARM1(x) ((x)->rdi) 59 | #define PT_REGS_PARM2(x) ((x)->rsi) 60 | #define PT_REGS_PARM3(x) ((x)->rdx) 61 | #define PT_REGS_PARM4(x) ((x)->rcx) 62 | #define PT_REGS_PARM5(x) ((x)->r8) 63 | #define PT_REGS_PARM6(x) ((x)->r9) 64 | #define PT_REGS_RC(x) ((x)->rax) 65 | 66 | #define MAX_CPU 512 67 | 68 | struct bpf_map_def SEC("maps") event_map = { 69 | .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, 70 | .key_size = sizeof(int), 71 | .value_size = sizeof(uint32_t), 72 | .max_entries = MAX_CPU, // 512 CPUs - this needs to accommodate most systems so make this big 73 | // Also, as this map is quite small (8 bytes per entry), we could potentially 74 | // make this even bigger and it woulnd't cost much 75 | }; 76 | 77 | // create a map to hold the event as we build it - too big for stack 78 | // one entry per cpu 79 | struct bpf_map_def SEC("maps") event_storage_map = { 80 | .type = BPF_MAP_TYPE_ARRAY, 81 | .key_size = sizeof(uint32_t), 82 | .value_size = sizeof(event_s), 83 | .max_entries = MAX_CPU, 84 | }; 85 | 86 | struct tracepoint__sched__sched_process_exit { 87 | uint64_t pad; 88 | char comm[16]; 89 | uint32_t pid; 90 | int32_t prio; 91 | }; 92 | 93 | struct raw_tracepoint__sched__sched_process_exit { 94 | void *p; 95 | }; 96 | 97 | 98 | __attribute__((always_inline)) 99 | static inline void write_event(void *ctx, pid_t pid, uint32_t type, char *exe) 100 | { 101 | uint32_t map_id = bpf_get_smp_processor_id(); 102 | event_s *event; 103 | int size = 0; 104 | 105 | // get memory for event 106 | event = bpf_map_lookup_elem(&event_storage_map, &map_id); 107 | if (event == NULL) { 108 | return; 109 | } 110 | 111 | event->pid = pid; 112 | event->size = 0; 113 | event->type = type; 114 | 115 | size = bpf_probe_read_str(event->exe, sizeof(event->exe), exe); 116 | if (size > 0) { 117 | event->size = size; 118 | } 119 | 120 | size = event->size & 4095; 121 | bpf_perf_event_output(ctx, &event_map, BPF_F_CURRENT_CPU, event, sizeof(*event) - sizeof(event->exe) + size); 122 | } 123 | 124 | __attribute__((flatten)) 125 | SEC("tracepoint/sched/sched_process_exit") 126 | int tracepoint__sched__sched_process_exit(struct tracepoint__sched__sched_process_exit *ctx) 127 | { 128 | uint64_t pid_tgid = bpf_get_current_pid_tgid(); 129 | 130 | write_event(ctx, ctx->pid, 1, ctx->comm); 131 | 132 | return 0; 133 | } 134 | 135 | __attribute__((flatten)) 136 | SEC("raw_tracepoint/sched/sched_process_exit") 137 | int raw_tracepoint__sched__sched_process_exit(struct raw_tracepoint__sched__sched_process_exit *ctx) 138 | { 139 | uint64_t pid_tgid = bpf_get_current_pid_tgid(); 140 | char comm[16]; 141 | 142 | bpf_get_current_comm(comm, sizeof(comm)); 143 | 144 | write_event(ctx, pid_tgid >> 32, 2, comm); 145 | 146 | return 0; 147 | } 148 | 149 | char _license[] SEC("license") = "GPL"; 150 | -------------------------------------------------------------------------------- /ebpfKern/HEADER: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | -------------------------------------------------------------------------------- /ebpfKern/makeEvent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SysmonForLinux 4 | # 5 | # Copyright (c) Microsoft Corporation 6 | # 7 | # All rights reserved. 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License along 20 | # with this program; if not, write to the Free Software Foundation, Inc., 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | # 23 | 24 | if [[ "$1" == "" ]]; then 25 | echo "$0: Make BPF event source code from templates" 26 | echo "$0 eventName" 27 | exit 1 28 | fi 29 | 30 | EVENT=$1 31 | 32 | cat sysmonTEMPLATE.c | sed -e "s/EVENT_NAME/${EVENT}/" > sysmon${EVENT}.c 33 | cat sysmonTEMPLATE_tp.c | sed -e "s/EVENT_NAME/${EVENT}/" > sysmon${EVENT}_tp.c 34 | cat sysmonTEMPLATE_rawtp.c | sed -e "s/EVENT_NAME/${EVENT}/" > sysmon${EVENT}_rawtp.c 35 | 36 | -------------------------------------------------------------------------------- /ebpfKern/sysmonCloseFD.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonCloseFD.c 26 | // 27 | // Removes PID/FD entry from inbound UDP tracking map. 28 | // 29 | //==================================================================== 30 | 31 | __attribute__((always_inline)) 32 | static inline void set_CloseFD_info( 33 | uint64_t pidTid, 34 | const argsStruct *eventArgs 35 | ) 36 | { 37 | uint64_t pidFd = 0; 38 | 39 | if (eventArgs == NULL) 40 | return; 41 | 42 | // only record successful actions 43 | if (eventArgs->returnCode != 0) 44 | return; 45 | 46 | pidFd = (pidTid & 0xFFFFFFFF00000000) | (eventArgs->a[0] & 0xFFFFFFFF); 47 | bpf_map_delete_elem(&UDPrecvAge, &pidFd); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /ebpfKern/sysmonCloseFD_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonCloseFD.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int CloseFDRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | argsStruct *eventArgs = NULL; 34 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 35 | const ebpfConfig *config; 36 | 37 | if (!setUpEvent(&config, &eventArgs)) 38 | return 0; 39 | 40 | // only handle close events 41 | if (eventArgs->syscallId != __NR_close) { 42 | return 0; 43 | } 44 | 45 | // set the return code 46 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 47 | BPF_PRINTK("ERROR, failed to get return code\n"); 48 | } 49 | 50 | set_CloseFD_info(pidTid, eventArgs); 51 | 52 | // Cleanup hash as we handled this event 53 | bpf_map_delete_elem(&argsHash, &pidTid); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /ebpfKern/sysmonCloseFD_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonCloseFD.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/CloseFD/exit") 32 | __attribute__((flatten)) 33 | int CloseFDExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | argsStruct *eventArgs = NULL; 37 | const ebpfConfig *config; 38 | 39 | if (!setUpEvent(&config, &eventArgs)) 40 | return 0; 41 | 42 | // set the return code 43 | eventArgs->returnCode = args->ret; 44 | 45 | set_CloseFD_info(pidTid, eventArgs); 46 | 47 | // Cleanup 48 | bpf_map_delete_elem(&argsHash, &pidTid); 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPF_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPF_common.h 26 | // 27 | // Includes and maps used by all eBPF programs. 28 | // 29 | //==================================================================== 30 | 31 | #ifndef SYSMON_EBPF_COMMON_H 32 | #define SYSMON_EBPF_COMMON_H 33 | 34 | #define SYSMON_EBPF 35 | 36 | #ifdef EBPF_CO_RE 37 | #include "vmlinux.h" 38 | #include "vmlinux_kern_diffs.h" 39 | #else 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #endif 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include "sysmon_defs.h" 58 | 59 | #define LINUX_MAX_EVENT_SIZE (65536 - 24) 60 | 61 | // defining file mode locally to remove requirement for heavy includes. 62 | // note that these *could* change, *but really aren't likely to*! 63 | #define S_IFMT 00170000 64 | #define S_IFREG 0100000 65 | #define S_IFBLK 0060000 66 | #define S_IFSOCK 0140000 67 | 68 | // create a map to hold the event as we build it - too big for stack 69 | // one entry per cpu 70 | struct { 71 | __uint(type, BPF_MAP_TYPE_ARRAY); 72 | __uint(key_size, sizeof(uint32_t)); 73 | __uint(value_size, LINUX_MAX_EVENT_SIZE); 74 | __uint(max_entries, MAX_PROC); 75 | } eventStorageMap SEC(".maps"); 76 | 77 | // create a map to hold the args as we build it - too big for stack 78 | // one entry per cpu 79 | struct { 80 | __uint(type, BPF_MAP_TYPE_ARRAY); 81 | __type(key, uint32_t); 82 | __type(value, argsStruct); 83 | __uint(max_entries, MAX_PROC); 84 | } argsStorageMap SEC(".maps"); 85 | 86 | 87 | // create a map to hold the packet as we access it - eBPF doesn't like 88 | // arbitrary access to stack buffers 89 | // one entry per cpu 90 | struct { 91 | __uint(type, BPF_MAP_TYPE_ARRAY); 92 | __uint(key_size, sizeof(uint32_t)); 93 | __uint(value_size, PACKET_SIZE); 94 | __uint(max_entries, MAX_PROC); 95 | } packetStorageMap SEC(".maps"); 96 | 97 | // create a map to hold the UDP recv age information 98 | struct { 99 | __uint(type, BPF_MAP_TYPE_HASH); 100 | __uint(max_entries, UDP_HASH_SIZE); 101 | __type(key, uint64_t); 102 | __type(value, uint64_t); 103 | } UDPrecvAge SEC(".maps"); 104 | 105 | 106 | // create a map to hold the UDP send age information 107 | struct { 108 | __uint(type, BPF_MAP_TYPE_HASH); 109 | __uint(max_entries, UDP_HASH_SIZE); 110 | __type(key, uint64_t); 111 | __type(value, uint64_t); 112 | } UDPsendAge SEC(".maps"); 113 | 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern4.15.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern4.15.c 26 | // 27 | // eBPF programs for kernel v4.15. 28 | // 29 | //==================================================================== 30 | 31 | #define SUB4096 1 32 | #define NOLOOPS 1 33 | 34 | #define FILEPATH_NUMDIRS 5 35 | 36 | #include "sysmonGenericEntry_tp.c" 37 | #include "sysmonProcCreate_tp.c" 38 | #include "sysmonFileCreate_tp.c" 39 | #include "sysmonFileOpen_tp.c" 40 | #include "sysmonFileDelete_tp.c" 41 | #include "sysmonFileDeleteAt_tp.c" 42 | #include "sysmonFileDeleteAtCwd_tp.c" 43 | #include "sysmonProcTerminated.c" 44 | #include "sysmonTCPaccept_tp.c" 45 | #include "sysmonTCPconnection_4_15.c" 46 | #include "sysmonProcAccessed_tp.c" 47 | #include "sysmonUDPsend.c" 48 | #include "sysmonUDPrecv_tp.c" 49 | #include "sysmonCloseFD_tp.c" 50 | 51 | char _license[] SEC("license") = "GPL"; 52 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern4.16.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern4.16.c 26 | // 27 | // eBPF programs for kernel v4.16. 28 | // 29 | //==================================================================== 30 | 31 | #define SUB4096 1 32 | #define NOLOOPS 1 33 | 34 | #define FILEPATH_NUMDIRS 5 35 | 36 | #include "sysmonGenericEntry_tp.c" 37 | #include "sysmonProcCreate_tp.c" 38 | #include "sysmonFileCreate_tp.c" 39 | #include "sysmonFileOpen_tp.c" 40 | #include "sysmonFileDelete_tp.c" 41 | #include "sysmonFileDeleteAt_tp.c" 42 | #include "sysmonFileDeleteAtCwd_tp.c" 43 | #include "sysmonProcTerminated.c" 44 | #include "sysmonTCPaccept_tp.c" 45 | #include "sysmonTCPconnection_4_16_5_5.c" 46 | #include "sysmonProcAccessed_tp.c" 47 | #include "sysmonUDPsend.c" 48 | #include "sysmonUDPrecv_tp.c" 49 | #include "sysmonCloseFD_tp.c" 50 | 51 | char _license[] SEC("license") = "GPL"; 52 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern4.17-5.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern4.17-5.1.c 26 | // 27 | // eBPF programs for kernel v4.17 to v5.1 inclusive. 28 | // 29 | //==================================================================== 30 | 31 | #define SUB4096 1 32 | #define NOLOOPS 1 33 | 34 | #define FILEPATH_NUMDIRS 5 35 | 36 | #include "sysmonGenericEntry_rawtp.c" 37 | #include "sysmonProcCreate_rawtp.c" 38 | #include "sysmonFileCreate_rawtp.c" 39 | #include "sysmonFileOpen_rawtp.c" 40 | #include "sysmonFileDelete_rawtp.c" 41 | #include "sysmonFileDeleteAt_rawtp.c" 42 | #include "sysmonFileDeleteAtCwd_rawtp.c" 43 | #include "sysmonProcTerminated.c" 44 | #include "sysmonTCPaccept_rawtp.c" 45 | #include "sysmonTCPconnection_4_16_5_5.c" 46 | #include "sysmonProcAccessed_rawtp.c" 47 | #include "sysmonUDPsend.c" 48 | #include "sysmonUDPrecv_rawtp.c" 49 | #include "sysmonCloseFD_rawtp.c" 50 | 51 | char _license[] SEC("license") = "GPL"; 52 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern5.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern5.2.c 26 | // 27 | // eBPF programs for kernel v5.2. 28 | // 29 | //==================================================================== 30 | 31 | #define NOLOOPS 1 32 | 33 | #define FILEPATH_NUMDIRS 13 34 | 35 | #include "sysmonGenericEntry_rawtp.c" 36 | #include "sysmonProcCreate_rawtp.c" 37 | #include "sysmonFileCreate_rawtp.c" 38 | #include "sysmonFileOpen_rawtp.c" 39 | #include "sysmonFileDelete_rawtp.c" 40 | #include "sysmonFileDeleteAt_rawtp.c" 41 | #include "sysmonFileDeleteAtCwd_rawtp.c" 42 | #include "sysmonProcTerminated.c" 43 | #include "sysmonTCPaccept_rawtp.c" 44 | #include "sysmonTCPconnection_4_16_5_5.c" 45 | #include "sysmonProcAccessed_rawtp.c" 46 | #include "sysmonUDPsend.c" 47 | #include "sysmonUDPrecv_rawtp.c" 48 | #include "sysmonCloseFD_rawtp.c" 49 | 50 | char _license[] SEC("license") = "GPL"; 51 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern5.3-5.5.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern5.3-5.5.c 26 | // 27 | // eBPF programs for kernel v5.3 to 5.5 inclusive. 28 | // 29 | //==================================================================== 30 | 31 | #define FILEPATH_NUMDIRS 32 32 | 33 | #include "sysmonGenericEntry_rawtp.c" 34 | #include "sysmonProcCreate_rawtp.c" 35 | #include "sysmonFileCreate_rawtp.c" 36 | #include "sysmonFileOpen_rawtp.c" 37 | #include "sysmonFileDelete_rawtp.c" 38 | #include "sysmonFileDeleteAt_rawtp.c" 39 | #include "sysmonFileDeleteAtCwd_rawtp.c" 40 | #include "sysmonProcTerminated.c" 41 | #include "sysmonTCPaccept_rawtp.c" 42 | #include "sysmonTCPconnection_4_16_5_5.c" 43 | #include "sysmonProcAccessed_rawtp.c" 44 | #include "sysmonUDPsend.c" 45 | #include "sysmonUDPrecv_rawtp.c" 46 | #include "sysmonCloseFD_rawtp.c" 47 | 48 | char _license[] SEC("license") = "GPL"; 49 | -------------------------------------------------------------------------------- /ebpfKern/sysmonEBPFkern5.6-.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonEBPFkern5.6-.c 26 | // 27 | // eBPF programs for kernel v5.6 and later. 28 | // 29 | //==================================================================== 30 | 31 | #define FILEPATH_NUMDIRS 16 32 | 33 | #include "sysmonGenericEntry_rawtp.c" 34 | #include "sysmonProcCreate_rawtp.c" 35 | #include "sysmonFileCreate_rawtp.c" 36 | #include "sysmonFileOpen_rawtp.c" 37 | #include "sysmonFileDelete_rawtp.c" 38 | #include "sysmonFileDeleteAt_rawtp.c" 39 | #include "sysmonFileDeleteAtCwd_rawtp.c" 40 | #include "sysmonProcTerminated.c" 41 | #include "sysmonTCPaccept_rawtp.c" 42 | #include "sysmonTCPconnection_5_6_.c" 43 | #include "sysmonProcAccessed_rawtp.c" 44 | #include "sysmonUDPsend.c" 45 | #include "sysmonUDPrecv_rawtp.c" 46 | #include "sysmonCloseFD_rawtp.c" 47 | 48 | char _license[] SEC("license") = "GPL"; 49 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileCreate.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonFileCreate.c 26 | // 27 | // Reports files created with creat() syscall. 28 | // 29 | //==================================================================== 30 | 31 | __attribute__((always_inline)) 32 | static inline char* set_fileCreate_ext( 33 | PSYSMON_FILE_CREATE event, 34 | const ebpfConfig *config, 35 | const argsStruct *eventArgs, 36 | const void *task 37 | ) 38 | { 39 | char *ptr = NULL; 40 | char *ptr2 = NULL; 41 | uint64_t extLen = 0; 42 | uint64_t pathLen = 0; 43 | char pathFirst = 0x00; 44 | int ret; 45 | const void *cred = NULL; 46 | 47 | ptr = (char *)(event + 1); 48 | memset(event->m_Extensions, 0, sizeof(event->m_Extensions)); 49 | 50 | // Insert the UID as the SID 51 | *(uint64_t *)ptr = getUid((struct task_struct*) task, config) & 0xFFFFFFFF; 52 | if(*(uint64_t *)ptr!=0) 53 | { 54 | event->m_Extensions[FC_Sid] = sizeof(uint64_t); 55 | ptr += sizeof(uint64_t); 56 | } 57 | 58 | extLen = copyExePath(ptr, task, config); 59 | event->m_Extensions[FC_ImagePath] = extLen; 60 | extLen &= (PATH_MAX -1); 61 | ptr += extLen; 62 | 63 | extLen = resolveFdPath(ptr, eventArgs->returnCode, task, config); 64 | 65 | event->m_Extensions[FC_FileName] = extLen; 66 | asm volatile("%[extLen] &= " XSTR(PATH_MAX - 1) "\n" 67 | "%[ptr] += %[extLen]" 68 | :[extLen]"+&r"(extLen), [ptr]"+&r"(ptr) 69 | ); 70 | 71 | return ptr; 72 | } 73 | 74 | __attribute__((always_inline)) 75 | static inline char* set_FileCreate_info( 76 | PSYSMON_EVENT_HEADER eventHdr, 77 | const ebpfConfig *config, 78 | uint64_t pidTid, 79 | uint32_t cpuId, 80 | const argsStruct *eventArgs 81 | ) 82 | { 83 | const void *task = NULL; 84 | 85 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 86 | return (char *)eventHdr; 87 | 88 | // only record successful actions 89 | if (eventArgs->returnCode == -1) 90 | return (char *)eventHdr; 91 | 92 | // get the task struct 93 | task = (void *)bpf_get_current_task(); 94 | if (!task) 95 | return (char *)eventHdr; 96 | 97 | // initialise event 98 | eventHdr->m_FieldFiltered = 0; 99 | eventHdr->m_PreFiltered = 0; 100 | eventHdr->m_SequenceNumber = 0; 101 | eventHdr->m_SessionId = 0; 102 | 103 | eventHdr->m_EventType = FileCreate; 104 | PSYSMON_FILE_CREATE event = &eventHdr->m_EventBody.m_FileCreateEvent; 105 | 106 | // set the pid 107 | event->m_ProcessId = pidTid >> 32; 108 | 109 | // set file create time - this is in nanoseconds and we want 100ns intervals 110 | event->m_CreateTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 111 | event->m_EventTime.QuadPart = event->m_CreateTime.QuadPart; 112 | 113 | // set hash 114 | event->m_hashType = 0; 115 | event->m_filehash[0] = 0x00; 116 | 117 | return set_fileCreate_ext(event, config, eventArgs, task); 118 | } 119 | 120 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileCreate_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonFileCreate.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int FileCreateRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | struct pt_regs *regs = (struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | const char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) { 41 | return 0; 42 | } 43 | 44 | // only handle file creation events 45 | if (eventArgs->syscallId != __NR_creat) { 46 | return 0; 47 | } 48 | 49 | // set the return code 50 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 51 | BPF_PRINTK("ERROR, failed to get return code\n"); 52 | } 53 | 54 | if (!getEventHdr(&eventHdr, cpuId)) { 55 | return 0; 56 | } 57 | 58 | ptr = set_FileCreate_info(eventHdr, config, pidTid, cpuId, eventArgs); 59 | if (ptr != NULL && ptr > eventHdr) { 60 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 61 | checkAndSendEvent((void *)ctx, eventHdr, config); 62 | } 63 | 64 | // Cleanup hash as we handled this event 65 | bpf_map_delete_elem(&argsHash, &pidTid); 66 | 67 | return 0; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileCreate_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonFileCreate.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/FileCreate/exit") 32 | __attribute__((flatten)) 33 | int FileCreateExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | const char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_FileCreate_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDelete.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonFileDelete.c 26 | // 27 | // Reports files deleted. 28 | // 29 | //==================================================================== 30 | 31 | __attribute__((always_inline)) 32 | static inline char* set_FileDelete_info( 33 | PSYSMON_EVENT_HEADER eventHdr, 34 | const ebpfConfig *config, 35 | uint64_t pidTid, 36 | uint32_t cpuId, 37 | const argsStruct *eventArgs 38 | ) 39 | { 40 | const void *task = NULL; 41 | const void *cred = NULL; 42 | char *ptr = NULL; 43 | char *ptr2 = NULL; 44 | const void *path_addr = NULL; 45 | bool relative = false; 46 | uint64_t extLen = 0; 47 | uint64_t pathLen = 0; 48 | char pathFirst = 0x00; 49 | 50 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 51 | return (char *)eventHdr; 52 | 53 | // only record successful actions 54 | if (eventArgs->returnCode != 0) 55 | return (char *)eventHdr; 56 | 57 | // get the task struct 58 | task = (const void *)bpf_get_current_task(); 59 | if (!task) 60 | return (char *)eventHdr; 61 | 62 | // initialise event 63 | eventHdr->m_FieldFiltered = 0; 64 | eventHdr->m_PreFiltered = 0; 65 | eventHdr->m_SequenceNumber = 0; 66 | eventHdr->m_SessionId = 0; 67 | 68 | eventHdr->m_EventType = FileDelete; 69 | PSYSMON_FILE_DELETE event = (PSYSMON_FILE_DELETE)&eventHdr->m_EventBody.m_FileDeleteEvent; 70 | 71 | // set the pid 72 | event->m_ProcessId = pidTid >> 32; 73 | 74 | // set event time - this is in nanoseconds and we want 100ns intervals 75 | event->m_DeleteTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 76 | 77 | event->m_HashType = 0; 78 | event->m_IsExecutable = 0; 79 | event->m_Archived[0] = 0x00; 80 | event->m_TrackerId = 0; 81 | 82 | path_addr = (const void *)eventArgs->a[0]; 83 | 84 | ptr = (char *)(event + 1); 85 | memset(event->m_Extensions, 0, sizeof(event->m_Extensions)); 86 | 87 | // Insert the UID as the SID 88 | *(uint64_t *)ptr = getUid((struct task_struct*) task, config) & 0xFFFFFFFF; 89 | if(*(uint64_t *)ptr!=0) 90 | { 91 | event->m_Extensions[FD_Sid] = sizeof(uint64_t); 92 | ptr += sizeof(uint64_t); 93 | } 94 | 95 | if (bpf_probe_read(&pathFirst, 1, path_addr) < 0) 96 | return (char *)eventHdr; 97 | 98 | if (pathFirst == '/') { 99 | relative = false; 100 | } else { 101 | relative = true; 102 | } 103 | 104 | if (relative) { 105 | // relative to current directory 106 | extLen = copyPwdPath(ptr, task, config); 107 | if (extLen <= 0) 108 | return (char *)eventHdr; 109 | extLen &= (PATH_MAX -1); 110 | ptr[extLen - 1] = '/'; 111 | ptr2 = ptr + extLen; 112 | pathLen = bpf_probe_read_str(ptr2, PATH_MAX, path_addr); 113 | if (pathLen < 0) 114 | return (char *)eventHdr; 115 | extLen += pathLen; 116 | event->m_Extensions[FD_FileName] = extLen; 117 | extLen &= ((PATH_MAX * 2) -1); 118 | ptr += extLen; 119 | } else { 120 | extLen = bpf_probe_read_str(ptr, PATH_MAX, path_addr); 121 | if (extLen <= 0) 122 | return (char *)eventHdr; 123 | event->m_Extensions[FD_FileName] = extLen; 124 | asm volatile("%[extLen] &= " XSTR(PATH_MAX - 1) "\n" 125 | "%[ptr] += %[extLen]" 126 | :[extLen]"+&r"(extLen), [ptr]"+&r"(ptr) 127 | ); 128 | } 129 | 130 | extLen = copyExePath(ptr, task, config); 131 | event->m_Extensions[FD_ImagePath] = extLen; 132 | extLen &= (MAX_PATH -1); 133 | ptr += extLen; 134 | 135 | return ptr; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDeleteAt.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonFileDeleteAt.c 26 | // 27 | // Reports files deleted. 28 | // 29 | //==================================================================== 30 | 31 | #include "missingdefs.h" 32 | 33 | __attribute__((always_inline)) 34 | static inline char* set_FileDeleteAt_info( 35 | PSYSMON_EVENT_HEADER eventHdr, 36 | const ebpfConfig *config, 37 | uint64_t pidTid, 38 | uint32_t cpuId, 39 | const argsStruct *eventArgs 40 | ) 41 | { 42 | const void *task = NULL; 43 | const void *cred = NULL; 44 | char *ptr = NULL; 45 | char *ptr2 = NULL; 46 | const void *path_addr = NULL; 47 | bool relative = false; 48 | uint64_t extLen = 0; 49 | uint64_t pathLen = 0; 50 | char pathFirst = 0x00; 51 | 52 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 53 | return (char *)eventHdr; 54 | 55 | // only record successful actions 56 | if (eventArgs->returnCode != 0) 57 | return (char *)eventHdr; 58 | 59 | // get the task struct 60 | task = (const void *)bpf_get_current_task(); 61 | if (!task) 62 | return (char *)eventHdr; 63 | 64 | // initialise event 65 | eventHdr->m_FieldFiltered = 0; 66 | eventHdr->m_PreFiltered = 0; 67 | eventHdr->m_SequenceNumber = 0; 68 | eventHdr->m_SessionId = 0; 69 | 70 | eventHdr->m_EventType = FileDelete; 71 | PSYSMON_FILE_DELETE event = (PSYSMON_FILE_DELETE)&eventHdr->m_EventBody.m_FileDeleteEvent; 72 | 73 | // set the pid 74 | event->m_ProcessId = pidTid >> 32; 75 | 76 | // set event time - this is in nanoseconds and we want 100ns intervals 77 | event->m_DeleteTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 78 | 79 | event->m_HashType = 0; 80 | event->m_IsExecutable = 0; 81 | event->m_Archived[0] = 0x00; 82 | event->m_TrackerId = 0; 83 | 84 | path_addr = (const void *)eventArgs->a[1]; 85 | if (eventArgs->a[2] == AT_REMOVEDIR) // equivalent to rmdir() rather than unlink() 86 | return (char *)eventHdr; 87 | 88 | ptr = (char *)(event + 1); 89 | memset(event->m_Extensions, 0, sizeof(event->m_Extensions)); 90 | 91 | // Insert the UID as the SID 92 | *(uint64_t *)ptr = getUid((struct task_struct*) task, config) & 0xFFFFFFFF; 93 | if(*(uint64_t *)ptr!=0) 94 | { 95 | event->m_Extensions[FD_Sid] = sizeof(uint64_t); 96 | ptr += sizeof(uint64_t); 97 | } 98 | 99 | if (bpf_probe_read(&pathFirst, 1, path_addr) < 0) 100 | return (char *)eventHdr; 101 | 102 | if (pathFirst == '/') { 103 | relative = false; 104 | } else { 105 | relative = true; 106 | } 107 | 108 | if (relative) { 109 | // relative to DFD 110 | extLen = resolveFdPath(ptr, eventArgs->a[0], task, config); 111 | if (extLen <= 0) 112 | return (char *)eventHdr; 113 | extLen &= (PATH_MAX -1); 114 | ptr[extLen - 1] = '/'; 115 | ptr2 = ptr + extLen; 116 | pathLen = bpf_probe_read_str(ptr2, PATH_MAX, path_addr); 117 | if (pathLen < 0) 118 | return (char *)eventHdr; 119 | extLen += pathLen; 120 | event->m_Extensions[FD_FileName] = extLen; 121 | extLen &= ((PATH_MAX * 2) -1); 122 | ptr += extLen; 123 | } else { 124 | extLen = bpf_probe_read_str(ptr, PATH_MAX, path_addr); 125 | if (extLen <= 0) 126 | return (char *)eventHdr; 127 | event->m_Extensions[FD_FileName] = extLen; 128 | asm volatile("%[extLen] &= " XSTR(PATH_MAX - 1) "\n" 129 | "%[ptr] += %[extLen]" 130 | :[extLen]"+&r"(extLen), [ptr]"+&r"(ptr) 131 | ); 132 | } 133 | 134 | extLen = copyExePath(ptr, task, config); 135 | event->m_Extensions[FD_ImagePath] = extLen; 136 | extLen &= (MAX_PATH -1); 137 | ptr += extLen; 138 | 139 | return ptr; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDeleteAtCwd_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonFileDeleteAtCwd.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int FileDeleteAtCwdRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle unlinkat events where DFD is AT_FDCWD 44 | if (eventArgs->syscallId != __NR_unlinkat || eventArgs->a[0] != (uint32_t)AT_FDCWD) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_FileDeleteAtCwd_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDeleteAtCwd_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonFileDeleteAtCwd.c" 28 | 29 | #include "missingdefs.h" 30 | 31 | // sys_exit 32 | SEC("sysmon/FileDeleteAtCwd/exit") 33 | __attribute__((flatten)) 34 | int FileDeleteAtCwdExit(struct tracepoint__syscalls__sys_exit *args) 35 | { 36 | uint64_t pidTid = bpf_get_current_pid_tgid(); 37 | uint32_t cpuId = bpf_get_smp_processor_id(); 38 | PSYSMON_EVENT_HEADER eventHdr = NULL; 39 | argsStruct *eventArgs = NULL; 40 | const ebpfConfig *config; 41 | char *ptr = NULL; 42 | 43 | if (!setUpEvent(&config, &eventArgs)) 44 | return 0; 45 | 46 | // only handle events where DFD is AT_FDCWD 47 | if (eventArgs->a[0] != AT_FDCWD) { 48 | return 0; 49 | } 50 | 51 | // set the return code 52 | eventArgs->returnCode = args->ret; 53 | 54 | if (!getEventHdr(&eventHdr, cpuId)) 55 | return 0; 56 | 57 | ptr = set_FileDeleteAtCwd_info(eventHdr, config, pidTid, cpuId, eventArgs); 58 | if (ptr != NULL && ptr > eventHdr) { 59 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 60 | checkAndSendEvent((void *)args, eventHdr, config); 61 | } 62 | 63 | // Cleanup 64 | bpf_map_delete_elem(&argsHash, &pidTid); 65 | 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDeleteAt_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonFileDeleteAt.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int FileDeleteAtRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle unlinkat events where the DFD is not AT_FDCWD 44 | if (eventArgs->syscallId != __NR_unlinkat || eventArgs->a[0] == (uint32_t)AT_FDCWD) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_FileDeleteAt_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDeleteAt_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonFileDeleteAt.c" 28 | 29 | #include "missingdefs.h" 30 | 31 | // sys_exit 32 | SEC("sysmon/FileDeleteAt/exit") 33 | __attribute__((flatten)) 34 | int FileDeleteAtExit(struct tracepoint__syscalls__sys_exit *args) 35 | { 36 | uint64_t pidTid = bpf_get_current_pid_tgid(); 37 | uint32_t cpuId = bpf_get_smp_processor_id(); 38 | PSYSMON_EVENT_HEADER eventHdr = NULL; 39 | argsStruct *eventArgs = NULL; 40 | const ebpfConfig *config; 41 | char *ptr = NULL; 42 | 43 | if (!setUpEvent(&config, &eventArgs)) 44 | return 0; 45 | 46 | // don't handle events where DFD is AT_FDCWD 47 | if (eventArgs->a[0] == AT_FDCWD) { 48 | return 0; 49 | } 50 | 51 | // set the return code 52 | eventArgs->returnCode = args->ret; 53 | 54 | if (!getEventHdr(&eventHdr, cpuId)) 55 | return 0; 56 | 57 | ptr = set_FileDeleteAt_info(eventHdr, config, pidTid, cpuId, eventArgs); 58 | if (ptr != NULL && ptr > eventHdr) { 59 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 60 | checkAndSendEvent((void *)args, eventHdr, config); 61 | } 62 | 63 | // Cleanup 64 | bpf_map_delete_elem(&argsHash, &pidTid); 65 | 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDelete_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonFileDelete.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int FileDeleteRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle unlink events 44 | if (eventArgs->syscallId != __NR_unlink) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_FileDelete_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileDelete_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonFileDelete.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/FileDelete/exit") 32 | __attribute__((flatten)) 33 | int FileDeleteExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_FileDelete_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileOpen_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonFileOpen.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int FileOpenRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle open and openat events 44 | if (eventArgs->syscallId != __NR_open && eventArgs->syscallId != __NR_openat) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_FileOpen_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonFileOpen_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonFileOpen.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/FileOpen/exit") 32 | __attribute__((flatten)) 33 | int FileOpenExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_FileOpen_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonGenericEntry_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonGenericEntry_rawtp.c 26 | // 27 | // Raw syscall entry program. 28 | // 29 | //==================================================================== 30 | 31 | #include "sysmonEBPF_common.h" 32 | #include 33 | 34 | 35 | // store the syscall arguments from the registers in the event 36 | __attribute__((always_inline)) 37 | static inline bool set_eventArgs(unsigned long *a, const struct pt_regs *regs) 38 | { 39 | int ret = 0; 40 | ret |= bpf_probe_read(&a[0], sizeof(a[0]), &SYSCALL_PT_REGS_PARM1(regs)); 41 | ret |= bpf_probe_read(&a[1], sizeof(a[1]), &SYSCALL_PT_REGS_PARM2(regs)); 42 | ret |= bpf_probe_read(&a[2], sizeof(a[2]), &SYSCALL_PT_REGS_PARM3(regs)); 43 | ret |= bpf_probe_read(&a[3], sizeof(a[3]), &SYSCALL_PT_REGS_PARM4(regs)); 44 | ret |= bpf_probe_read(&a[4], sizeof(a[4]), &SYSCALL_PT_REGS_PARM5(regs)); 45 | ret |= bpf_probe_read(&a[5], sizeof(a[5]), &SYSCALL_PT_REGS_PARM6(regs)); 46 | if (!ret) 47 | return true; 48 | else 49 | return false; 50 | } 51 | 52 | 53 | SEC("raw_tracepoint/sys_enter") 54 | __attribute__((flatten)) 55 | int genericRawEnter(struct bpf_our_raw_tracepoint_args *ctx) 56 | { 57 | uint64_t pidTid = bpf_get_current_pid_tgid(); 58 | uint32_t cpuId = bpf_get_smp_processor_id(); 59 | argsStruct *eventArgs; 60 | uint32_t syscall = ctx->args[1]; 61 | uint32_t configId = 0; 62 | const ebpfConfig *config; 63 | const void *task; 64 | 65 | // retrieve config 66 | config = bpf_map_lookup_elem(&configMap, &configId); 67 | if (!config) { 68 | return 0; 69 | } 70 | 71 | // bail early for syscalls we aren't interested in 72 | if (!config->active[syscall & (SYSCALL_ARRAY_SIZE - 1)]) { 73 | return 0; 74 | } 75 | 76 | // retrieve map storage for event 77 | eventArgs = bpf_map_lookup_elem(&argsStorageMap, &cpuId); 78 | if (!eventArgs) { 79 | return 0; 80 | } 81 | 82 | if (!sysEnterCheckAndInit(eventArgs, config, syscall, pidTid)) { 83 | return 0; 84 | } 85 | 86 | // retrieve the register state 87 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 88 | 89 | if (!set_eventArgs(eventArgs->a, regs)) { 90 | BPF_PRINTK("set_eventArgs failed\n"); 91 | } 92 | sysEnterCompleteAndStore(eventArgs, syscall, pidTid); 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcAccessed.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonProcAccessed.c 26 | // 27 | // Report use of ptrace(). 28 | // 29 | //==================================================================== 30 | 31 | #include "missingdefs.h" 32 | 33 | 34 | __attribute__((always_inline)) 35 | static inline char* set_ProcAccessed_info( 36 | PSYSMON_EVENT_HEADER eventHdr, 37 | const ebpfConfig *config, 38 | uint64_t pidTid, 39 | uint32_t cpuId, 40 | const argsStruct *eventArgs 41 | ) 42 | { 43 | const void *task = NULL; 44 | char *ptr = NULL; 45 | uint64_t extLen = 0; 46 | const void *cred = NULL; 47 | 48 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 49 | return (char *)eventHdr; 50 | 51 | // only record successful actions 52 | if (eventArgs->returnCode != 0) 53 | return (char *)eventHdr; 54 | 55 | // only record PTRACE_ATTACH and PTRACE_SEIZE events 56 | if (eventArgs->a[0] != PTRACE_ATTACH && eventArgs->a[0] != PTRACE_SEIZE) 57 | return (char *)eventHdr; 58 | 59 | // get the task struct 60 | task = (const void *)bpf_get_current_task(); 61 | if (!task) 62 | return (char *)eventHdr; 63 | 64 | // initialise event 65 | eventHdr->m_FieldFiltered = 0; 66 | eventHdr->m_PreFiltered = 0; 67 | eventHdr->m_SequenceNumber = 0; 68 | eventHdr->m_SessionId = 0; 69 | 70 | eventHdr->m_EventType = ProcessAccess; 71 | PSYSMON_PROCESS_ACCESS event = (PSYSMON_PROCESS_ACCESS)&eventHdr->m_EventBody.m_ProcessAccessEvent; 72 | 73 | // set the pid and tid 74 | event->m_ClientProcessID = pidTid >> 32; 75 | event->m_ClientThreadID = pidTid & (0xFFFFFFFF); 76 | 77 | // set event time - this is in nanoseconds and we want 100ns intervals 78 | event->m_EventSystemTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 79 | 80 | // set target pid 81 | event->m_TargetPid = eventArgs->a[1]; 82 | 83 | // we don't use GrantedAccess 84 | event->m_GrantedAccess = 0; 85 | 86 | ptr = (char *)(event + 1); 87 | memset(event->m_Extensions, 0, sizeof(event->m_Extensions)); 88 | extLen = copyExePath(ptr, task, config); 89 | event->m_Extensions[PA_ClientImage] = extLen; 90 | asm volatile("%[extLen] &= " XSTR(PATH_MAX - 1) "\n" 91 | "%[ptr] += %[extLen]" 92 | :[extLen]"+&r"(extLen), [ptr]"+&r"(ptr) 93 | ); 94 | 95 | // Insert the UID as the SID 96 | *(uint64_t *)ptr = getUid((struct task_struct*) task, config) & 0xFFFFFFFF; 97 | if(*(uint64_t *)ptr!=0) 98 | { 99 | event->m_Extensions[PA_SidSource] = sizeof(uint64_t); 100 | ptr += sizeof(uint64_t); 101 | } 102 | 103 | return ptr; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcAccessed_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonProcAccessed.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int ProcAccessedRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle X events 44 | if (eventArgs->syscallId != __NR_ptrace) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_ProcAccessed_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcAccessed_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonProcAccessed.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/ProcAccessed/exit") 32 | __attribute__((flatten)) 33 | int ProcAccessedExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_ProcAccessed_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcCreate_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonProcCreate.c" 28 | 29 | SEC("raw_tracepoint/sys_exit") 30 | __attribute__((flatten)) 31 | int ProcCreateRawExit(struct bpf_our_raw_tracepoint_args *ctx) 32 | { 33 | uint64_t pidTid = bpf_get_current_pid_tgid(); 34 | uint32_t cpuId = bpf_get_smp_processor_id(); 35 | PSYSMON_EVENT_HEADER eventHdr = NULL; 36 | argsStruct *eventArgs = NULL; 37 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 38 | const ebpfConfig *config; 39 | char *ptr = NULL; 40 | 41 | if (!setUpEvent(&config, &eventArgs)) { 42 | return 0; 43 | } 44 | 45 | // only handle process creation events 46 | if (eventArgs->syscallId != __NR_execve && 47 | eventArgs->syscallId != __NR_execveat) { 48 | return 0; 49 | } 50 | 51 | // set the return code 52 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 53 | BPF_PRINTK("ERROR, failed to get return code\n"); 54 | } 55 | 56 | if (!getEventHdr(&eventHdr, cpuId)) { 57 | return 0; 58 | } 59 | 60 | ptr = set_ProcCreate_info(eventHdr, config, pidTid, cpuId, eventArgs); 61 | if (ptr != NULL && ptr > eventHdr) { 62 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 63 | checkAndSendEvent((void *)ctx, eventHdr, config); 64 | } 65 | 66 | // Cleanup hash as we handled this event 67 | bpf_map_delete_elem(&argsHash, &pidTid); 68 | 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcCreate_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonProcCreate.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/ProcCreate/exit") 32 | __attribute__((flatten)) 33 | int ProcCreateExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_ProcCreate_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonProcTerminated.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonProcTerminated.c 26 | // 27 | // Report process termination events. 28 | // 29 | //==================================================================== 30 | 31 | #include "sysmonEBPF_common.h" 32 | #include 33 | #include "sysmonHelpers.c" 34 | 35 | struct tracepoint__sched__sched_process_exit { 36 | __uint64_t pad; 37 | char comm[16]; 38 | pid_t pid; 39 | int prio; 40 | }; 41 | 42 | // process terminated 43 | SEC("tracepoint/sched/sched_process_exit") 44 | __attribute__((flatten)) 45 | int ProcTerminated(struct tracepoint__sched__sched_process_exit *args) 46 | { 47 | uint64_t pidTid; 48 | uint32_t cpuId = bpf_get_smp_processor_id(); 49 | PSYSMON_EVENT_HEADER eventHdr = NULL; 50 | const ebpfConfig *config; 51 | char *ptr = NULL; 52 | const void *task = NULL; 53 | const void *cred = NULL; 54 | 55 | if (!getConfig(&config, &pidTid)) 56 | return 0; 57 | 58 | if (!getEventHdr(&eventHdr, cpuId)) 59 | return 0; 60 | 61 | if (!config->active[__NR_PROCTERM]) 62 | return 0; 63 | 64 | // initialise event 65 | eventHdr->m_FieldFiltered = 0; 66 | eventHdr->m_PreFiltered = 0; 67 | eventHdr->m_SequenceNumber = 0; 68 | eventHdr->m_SessionId = 0; 69 | 70 | eventHdr->m_EventType = ProcessTerminate; 71 | PSYSMON_PROCESS_TERMINATE event = (PSYSMON_PROCESS_TERMINATE)&eventHdr->m_EventBody.m_ProcessTerminateEvent; 72 | 73 | event->m_ProcessId = pidTid >> 32; 74 | event->m_EventTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 75 | 76 | ptr = (char *)(event + 1); 77 | 78 | // get the task struct 79 | task = (const void *)bpf_get_current_task(); 80 | 81 | // Insert the UID as the SID 82 | if (task) { 83 | *(uint64_t *)ptr = getUid((struct task_struct*) task, config) & 0xFFFFFFFF; 84 | if(*(uint64_t *)ptr!=0) 85 | { 86 | event->m_Extensions[PT_Sid] = sizeof(uint64_t); 87 | ptr += sizeof(uint64_t); 88 | } 89 | } 90 | 91 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 92 | checkAndSendEvent((void *)args, eventHdr, config); 93 | 94 | return 0; 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTCPaccept.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonTCPaccept.c 26 | // 27 | // Report successful accept() calls for inbound network connections. 28 | // 29 | //==================================================================== 30 | 31 | __attribute__((always_inline)) 32 | static inline const char* set_TCPaccept_info( 33 | PSYSMON_EVENT_HEADER eventHdr, 34 | const ebpfConfig *config, 35 | uint64_t pidTid, 36 | uint32_t cpuId, 37 | const argsStruct *eventArgs 38 | ) 39 | { 40 | const void *task = NULL; 41 | const char *ptr = NULL; 42 | struct sockaddr_in s_addr; 43 | struct sockaddr_in6 s_addr6; 44 | uint32_t socklen; 45 | 46 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 47 | return (char *)eventHdr; 48 | 49 | // only record successful actions 50 | if (eventArgs->returnCode == -1) 51 | return (char *)eventHdr; 52 | 53 | // get the task struct 54 | task = (const void *)bpf_get_current_task(); 55 | if (!task) 56 | return (char *)eventHdr; 57 | 58 | // initialise event 59 | eventHdr->m_FieldFiltered = 0; 60 | eventHdr->m_PreFiltered = 0; 61 | eventHdr->m_SequenceNumber = 0; 62 | eventHdr->m_SessionId = 0; 63 | 64 | eventHdr->m_EventType = LinuxNetworkEvent; 65 | PSYSMON_LINUX_NETWORK_EVENT event = (PSYSMON_LINUX_NETWORK_EVENT)&eventHdr->m_EventBody; 66 | 67 | // set the pid 68 | event->m_ProcessId = pidTid >> 32; 69 | 70 | // set event time - this is in nanoseconds and we want 100ns intervals 71 | event->m_EventTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 72 | 73 | event->m_IsTCP = true; 74 | event->m_OldState = TCP_LISTEN; 75 | event->m_NewState = TCP_ESTABLISHED; 76 | event->m_DstPort = 0; 77 | event->m_SockId = (void *)eventArgs->returnCode; 78 | 79 | memset(event->m_SrcAddr, 0, sizeof(event->m_SrcAddr)); 80 | memset(event->m_DstAddr, 0, sizeof(event->m_DstAddr)); 81 | 82 | ptr = (const char *)(event + 1); 83 | 84 | bpf_probe_read(&socklen, sizeof(socklen), (void *)eventArgs->a[2]); 85 | 86 | if (socklen <= sizeof(struct sockaddr_in)) { 87 | bpf_probe_read(&s_addr, sizeof(s_addr), (void *)eventArgs->a[1]); 88 | event->m_AddrIsIPv4 = true; 89 | bpf_probe_read(event->m_SrcAddr, 4, (void *)&(s_addr.sin_addr)); 90 | event->m_SrcPort = (s_addr.sin_port >> 8) | ((s_addr.sin_port & 0xFF) << 8); 91 | } else { 92 | bpf_probe_read(&s_addr6, sizeof(s_addr6), (void *)eventArgs->a[1]); 93 | event->m_AddrIsIPv4 = false; 94 | bpf_probe_read(event->m_SrcAddr, 16, (void *)&(s_addr6.sin6_addr)); 95 | event->m_SrcPort = (s_addr6.sin6_port >> 8) | ((s_addr6.sin6_port & 0xFF) << 8); 96 | } 97 | 98 | return ptr; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTCPaccept_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonTCPaccept.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int TCPacceptRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | const char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle X events 44 | if (eventArgs->syscallId != __NR_accept && eventArgs->syscallId != __NR_accept4) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_TCPaccept_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTCPaccept_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonTCPaccept.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/TCPaccept/exit") 32 | __attribute__((flatten)) 33 | int TCPacceptExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | const char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_TCPaccept_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTCPconnection_4_15.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonTCPconnection_4_15.c 26 | // 27 | // Report TCP state change on kernel v4.15. 28 | // 29 | //==================================================================== 30 | 31 | #include "sysmonEBPF_common.h" 32 | #include 33 | #include "sysmonHelpers.c" 34 | 35 | struct tracepoint__tcp__tcp_set_state { 36 | __uint64_t pad; 37 | const void *skaddr; // kernel struct sock * 38 | int oldstate; 39 | int newstate; 40 | __u16 sport; 41 | __u16 dport; 42 | __u8 saddr[4]; 43 | __u8 daddr[4]; 44 | __u8 saddr_v6[16]; 45 | __u8 daddr_v6[16]; 46 | }; 47 | 48 | // network connection state change 49 | SEC("tracepoint/tcp/tcp_set_state") 50 | __attribute__((flatten)) 51 | int TCPconnectionOld(struct tracepoint__tcp__tcp_set_state *args) 52 | { 53 | uint64_t pidTid; 54 | uint32_t cpuId = bpf_get_smp_processor_id(); 55 | PSYSMON_EVENT_HEADER eventHdr = NULL; 56 | const ebpfConfig *config; 57 | char *ptr = NULL; 58 | const void *task = NULL; 59 | uint64_t extLen = 0; 60 | uint32_t pid = 0; 61 | 62 | if (!getConfig(&config, &pidTid)) 63 | return 0; 64 | 65 | if (!getEventHdr(&eventHdr, cpuId)) 66 | return 0; 67 | 68 | if (!config->active[__NR_NETWORK]) 69 | return 0; 70 | 71 | // get the task struct 72 | task = (const void *)bpf_get_current_task(); 73 | if (!task) 74 | return 0; 75 | 76 | if (!(args->newstate == TCP_SYN_SENT 77 | || (args->oldstate == TCP_SYN_SENT && args->newstate == TCP_ESTABLISHED) 78 | || (args->oldstate == TCP_SYN_RECV && args->newstate == TCP_ESTABLISHED) 79 | || (args->newstate == TCP_CLOSE))) 80 | // only interested in connections that being initiated, connected or closed 81 | return 0; 82 | 83 | // initialise event 84 | eventHdr->m_FieldFiltered = 0; 85 | eventHdr->m_PreFiltered = 0; 86 | eventHdr->m_SequenceNumber = 0; 87 | eventHdr->m_SessionId = 0; 88 | 89 | eventHdr->m_EventType = LinuxNetworkEvent; 90 | PSYSMON_LINUX_NETWORK_EVENT event = (PSYSMON_LINUX_NETWORK_EVENT)&eventHdr->m_EventBody; 91 | 92 | event->m_ProcessId = pidTid >> 32; // this might not match the related process 93 | event->m_EventTime.QuadPart = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 94 | 95 | event->m_IsTCP = true; 96 | event->m_SockId = args->skaddr; 97 | event->m_OldState = args->oldstate; 98 | event->m_NewState = args->newstate; 99 | event->m_SrcPort = args->sport; 100 | event->m_DstPort = args->dport; 101 | 102 | memset(event->m_SrcAddr, 0, sizeof(event->m_SrcAddr)); 103 | memset(event->m_DstAddr, 0, sizeof(event->m_DstAddr)); 104 | 105 | ptr = (char *)(event + 1); 106 | 107 | if (*(uint32_t *)args->saddr != 0) { 108 | event->m_AddrIsIPv4 = true; 109 | bpf_probe_read(event->m_SrcAddr, sizeof(args->saddr), (void *)args->saddr); 110 | bpf_probe_read(event->m_DstAddr, sizeof(args->daddr), (void *)args->daddr); 111 | } else { 112 | event->m_AddrIsIPv4 = false; 113 | bpf_probe_read(event->m_SrcAddr, sizeof(args->saddr_v6), (void *)args->saddr_v6); 114 | bpf_probe_read(event->m_DstAddr, sizeof(args->daddr_v6), (void *)args->daddr_v6); 115 | } 116 | 117 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 118 | checkAndSendEvent((void *)args, eventHdr, config); 119 | 120 | return 0; 121 | } 122 | 123 | 124 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTEMPLATE.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonTEMPLATE.c 26 | // 27 | // Template code to report syscall functionality. 28 | // 29 | //==================================================================== 30 | 31 | __attribute__((always_inline)) 32 | static inline char* set_EVENT_NAME_info( 33 | PSYSMON_EVENT_HEADER eventHdr, 34 | const ebpfConfig *config, 35 | uint64_t pidTid, 36 | uint32_t cpuId, 37 | const argsStruct *eventArgs 38 | ) 39 | { 40 | const void *task = NULL; 41 | char *ptr = NULL; 42 | 43 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 44 | return (char *)eventHdr; 45 | 46 | // only record successful actions 47 | if (eventArgs->returnCode != 0) 48 | return (char *)eventHdr; 49 | 50 | // get the task struct 51 | task = (const void *)bpf_get_current_task(); 52 | if (!task) 53 | return (char *)eventHdr; 54 | 55 | // initialise event 56 | eventHdr->m_FieldFiltered = 0; 57 | eventHdr->m_PreFiltered = 0; 58 | eventHdr->m_SequenceNumber = 0; 59 | eventHdr->m_SessionId = 0; 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTEMPLATE_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonEVENT_NAME.c" 27 | 28 | SEC("sysmon/EVENT_NAME/rawExit") 29 | __attribute__((flatten)) 30 | int EVENT_NAMERawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle X events 44 | if (eventArgs->syscallId != X) { 45 | return 0; 46 | } 47 | 48 | // set the return code 49 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 50 | BPF_PRINTK("ERROR, failed to get return code\n"); 51 | } 52 | 53 | if (!getEventHdr(&eventHdr, cpuId)) 54 | return 0; 55 | 56 | ptr = set_EVENT_NAME_info(eventHdr, config, pidTid, cpuId, eventArgs); 57 | if (ptr != NULL && ptr > eventHdr) { 58 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 59 | checkAndSendEvent((void *)ctx, eventHdr, config); 60 | } 61 | 62 | // Cleanup hash as we handled this event 63 | bpf_map_delete_elem(&argsHash, &pidTid); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ebpfKern/sysmonTEMPLATE_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonEVENT_NAME.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/EVENT_NAME/exit") 32 | __attribute__((flatten)) 33 | int EVENT_NAMEExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_EVENT_NAME_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /ebpfKern/sysmonUDPrecv.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | //==================================================================== 24 | // 25 | // sysmonUDPrecv.c 26 | // 27 | // Report successful calls to read()/recv()/recvmsg()/recvmmsg() 28 | // where the FD is a socket and it hasn't been reported recently. 29 | // This is used to identify UDP packets being received. 30 | // 31 | //==================================================================== 32 | 33 | __attribute__((always_inline)) 34 | static inline char* set_UDPrecv_info( 35 | PSYSMON_EVENT_HEADER eventHdr, 36 | const ebpfConfig *config, 37 | uint64_t pidTid, 38 | uint32_t cpuId, 39 | const argsStruct *eventArgs 40 | ) 41 | { 42 | const void *task = NULL; 43 | char *ptr = NULL; 44 | const void *inode = NULL; 45 | uint32_t mode = 0; 46 | uint64_t pidFd = 0; 47 | LONGLONG *lastTimeAddr = NULL; 48 | LONGLONG lastTime = 0; 49 | LONGLONG curTime = 0; 50 | struct sockaddr_in s_addr; 51 | struct sockaddr_in6 s_addr6; 52 | uint32_t socklen; 53 | 54 | if (eventHdr == NULL || config == NULL || eventArgs == NULL) 55 | return (char *)eventHdr; 56 | 57 | // only record successful actions 58 | if (eventArgs->returnCode == -1) 59 | return (char *)eventHdr; 60 | 61 | // get the task struct 62 | task = (const void *)bpf_get_current_task(); 63 | if (!task) 64 | return (char *)eventHdr; 65 | 66 | // get the last time we saw this (0 == TCP) 67 | pidFd = (pidTid & 0xFFFFFFFF00000000) | (eventArgs->a[0] & 0xFFFFFFFF); 68 | lastTimeAddr = (LONGLONG *)bpf_map_lookup_elem(&UDPrecvAge, &pidFd); 69 | if (lastTimeAddr == NULL) { 70 | lastTime = -1; 71 | } else { 72 | lastTime = *lastTimeAddr; 73 | } 74 | 75 | if (lastTime == 0) 76 | // TCP FD 77 | return (char *)eventHdr; 78 | 79 | // get the current time 80 | curTime = (bpf_ktime_get_ns() + config->bootNsSinceEpoch) / 100; 81 | 82 | if (lastTime == -1) { 83 | // Not in hash 84 | 85 | inode = derefInodeFromFd(task, eventArgs->a[0], config); 86 | 87 | // a valid call must have a valid inode 88 | if (inode == NULL) 89 | return (char *)eventHdr; 90 | 91 | #ifdef EBPF_CO_RE 92 | mode = BPF_CORE_READ((struct inode *)inode, i_mode); 93 | #else 94 | bpf_probe_read(&mode, sizeof(mode), inode + config->offsets.inode_mode[0]); 95 | #endif 96 | 97 | // and a socket action must be on a socket 98 | if ((mode & S_IFMT) != S_IFSOCK) 99 | return (char *)eventHdr; 100 | 101 | } else { 102 | // exists in hash 103 | 104 | // only act on sockets we haven't seen or ones we haven't seen lately 105 | if (curTime - lastTime < UDP_REPORT_INTERVAL) 106 | return (char *)eventHdr; 107 | } 108 | 109 | // insert/update the hash 110 | bpf_map_update_elem(&UDPrecvAge, &pidFd, &curTime, BPF_ANY); 111 | 112 | // initialise event 113 | eventHdr->m_FieldFiltered = 0; 114 | eventHdr->m_PreFiltered = 0; 115 | eventHdr->m_SequenceNumber = 0; 116 | eventHdr->m_SessionId = 0; 117 | 118 | eventHdr->m_EventType = LinuxNetworkEvent; 119 | PSYSMON_LINUX_NETWORK_EVENT event = (PSYSMON_LINUX_NETWORK_EVENT)&eventHdr->m_EventBody; 120 | 121 | event->m_ProcessId = pidTid >> 32; 122 | event->m_EventTime.QuadPart = curTime; 123 | 124 | event->m_IsTCP = false; 125 | event->m_SockId = (const void *)(eventArgs->a[0] & 0xFFFFFFFF); 126 | 127 | memset(event->m_SrcAddr, 0, sizeof(event->m_SrcAddr)); 128 | memset(event->m_DstAddr, 0, sizeof(event->m_DstAddr)); 129 | event->m_SrcPort = 0; 130 | event->m_DstPort = 0; 131 | 132 | ptr = (char *)(event + 1); 133 | 134 | return ptr; 135 | } 136 | 137 | -------------------------------------------------------------------------------- /ebpfKern/sysmonUDPrecv_rawtp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | #include "sysmonEBPF_common.h" 24 | #include 25 | #include "sysmonHelpers.c" 26 | #include "sysmonUDPrecv.c" 27 | 28 | SEC("raw_tracepoint/sys_exit") 29 | __attribute__((flatten)) 30 | int UDPrecvRawExit(struct bpf_our_raw_tracepoint_args *ctx) 31 | { 32 | uint64_t pidTid = bpf_get_current_pid_tgid(); 33 | uint32_t cpuId = bpf_get_smp_processor_id(); 34 | PSYSMON_EVENT_HEADER eventHdr = NULL; 35 | argsStruct *eventArgs = NULL; 36 | const struct pt_regs *regs = (const struct pt_regs *)ctx->args[0]; 37 | const ebpfConfig *config; 38 | char *ptr = NULL; 39 | 40 | if (!setUpEvent(&config, &eventArgs)) 41 | return 0; 42 | 43 | // only handle socket read and write events 44 | if (eventArgs->syscallId != __NR_recvfrom && 45 | eventArgs->syscallId != __NR_recvmsg && 46 | eventArgs->syscallId != __NR_recvmmsg && 47 | eventArgs->syscallId != __NR_read) { 48 | return 0; 49 | } 50 | 51 | // set the return code 52 | if (bpf_probe_read(&eventArgs->returnCode, sizeof(int64_t), (void *)&SYSCALL_PT_REGS_RC(regs)) != 0){ 53 | BPF_PRINTK("ERROR, failed to get return code\n"); 54 | } 55 | 56 | if (!getEventHdr(&eventHdr, cpuId)) 57 | return 0; 58 | 59 | ptr = set_UDPrecv_info(eventHdr, config, pidTid, cpuId, eventArgs); 60 | if (ptr != NULL && ptr > eventHdr) { 61 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 62 | checkAndSendEvent((void *)ctx, eventHdr, config); 63 | } 64 | 65 | // Cleanup hash as we handled this event 66 | bpf_map_delete_elem(&argsHash, &pidTid); 67 | 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /ebpfKern/sysmonUDPrecv_tp.c: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | #include "sysmonEBPF_common.h" 25 | #include 26 | #include "sysmonHelpers.c" 27 | #include "sysmonUDPrecv.c" 28 | 29 | 30 | // sys_exit 31 | SEC("sysmon/UDPrecv/exit") 32 | __attribute__((flatten)) 33 | int UDPrecvExit(struct tracepoint__syscalls__sys_exit *args) 34 | { 35 | uint64_t pidTid = bpf_get_current_pid_tgid(); 36 | uint32_t cpuId = bpf_get_smp_processor_id(); 37 | PSYSMON_EVENT_HEADER eventHdr = NULL; 38 | argsStruct *eventArgs = NULL; 39 | const ebpfConfig *config; 40 | char *ptr = NULL; 41 | 42 | if (!setUpEvent(&config, &eventArgs)) 43 | return 0; 44 | 45 | // set the return code 46 | eventArgs->returnCode = args->ret; 47 | 48 | if (!getEventHdr(&eventHdr, cpuId)) 49 | return 0; 50 | 51 | ptr = set_UDPrecv_info(eventHdr, config, pidTid, cpuId, eventArgs); 52 | if (ptr != NULL && ptr > eventHdr) { 53 | eventHdr->m_EventSize = (uint32_t)((void *)ptr - (void *)eventHdr); 54 | checkAndSendEvent((void *)args, eventHdr, config); 55 | } 56 | 57 | // Cleanup 58 | bpf_map_delete_elem(&argsHash, &pidTid); 59 | 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /extractMsgMc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SysmonForLinux 4 | # 5 | # Copyright (c) Microsoft Corporation 6 | # 7 | # All rights reserved. 8 | # 9 | # MIT License 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | ################################################################################# 19 | # 20 | # extractMsgMc.sh 21 | # 22 | # Extracts defines from sysmonmsg.mc 23 | # 24 | ################################################################################# 25 | 26 | 27 | SYSMONMSG=sysmonmsg.mc 28 | 29 | echo "// Copyright (c) 2021 Microsoft Corporation" 30 | 31 | LINE1=`grep -n SeverityNames $SYSMONMSG | cut -d: -f1` 32 | LINE2=`tail -n +$LINE1 $SYSMONMSG | grep -n ')' | head -n 1 | cut -d: -f1` 33 | tail -n +$LINE1 $SYSMONMSG | head -n $LINE2 | grep : | sed -e 's/)//' | sed -e 's/^.*=0x\([^:]*\):\(.*\)$/#define \2 0x\1/' 34 | 35 | LINE1=`grep -n FacilityNames $SYSMONMSG | cut -d: -f1` 36 | LINE2=`tail -n +$LINE1 $SYSMONMSG | grep -n ')' | head -n 1 | cut -d: -f1` 37 | tail -n +$LINE1 $SYSMONMSG | head -n $LINE2 | grep : | sed -e 's/)//' | sed -e 's/^.*=0x\([^:]*\):\(.*\)$/#define \2 0x\1/' 38 | 39 | grep '^MessageId=0x.* Facility=Serial Severity=Error' $SYSMONMSG | sed -e 's/^MessageId=\(0x[^ ]*\).*SymbolicName=\(.*\)$/#define \2 ((NTSTATUS)(0xC0060000L + \1))/' 40 | grep '^MessageId=0x.* Facility=Serial Severity=Warning' $SYSMONMSG | sed -e 's/^MessageId=\(0x[^ ]*\).*SymbolicName=\(.*\)$/#define \2 ((NTSTATUS)(0x80060000L + \1))/' 41 | grep '^MessageId=0x.* Facility=Serial Severity=Informational' $SYSMONMSG | sed -e 's/^MessageId=\(0x[^ ]*\).*SymbolicName=\(.*\)$/#define \2 ((NTSTATUS)(0x40060000L + \1))/' 42 | grep '^MessageId=0x.* Facility=Serial Severity=Success' $SYSMONMSG | sed -e 's/^MessageId=\(0x[^ ]*\).*SymbolicName=\(.*\)$/#define \2 ((NTSTATUS)(0x00060000L + \1))/' 43 | -------------------------------------------------------------------------------- /extractMsgOp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SysmonForLinux 4 | # 5 | # Copyright (c) Microsoft Corporation 6 | # 7 | # All rights reserved. 8 | # 9 | # MIT License 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | ################################################################################# 19 | # 20 | # extractMsgOp.sh 21 | # 22 | # Extracts defines from sysmonmsgop.man 23 | # 24 | ################################################################################# 25 | 26 | SYSMONMSGOP=sysmonmsgop.man 27 | if [[ "$1" == "HEADER" ]]; then 28 | # H file 29 | echo "// Copyright (c) 2021 Microsoft Corporation." 30 | echo "" 31 | echo "#pragma once" 32 | echo "" 33 | echo "extern const GUID SYSMON_PROVIDER;" 34 | echo "#define SYSMON_CHANNEL 0x10" 35 | echo "" 36 | grep '>1))) 48 | X=$((X | (X>>2))) 49 | X=$((X | (X>>4))) 50 | X=$((X | (X>>8))) 51 | X=$((X | (X>>16))) 52 | echo "// EVENT_COUNT_P2 is always the power of 2 equal or greater" 53 | echo "// than the actual number of events, for easy eBPF maths" 54 | echo "#define EVENT_COUNT_P2 " $((X + 1)) 55 | 56 | else 57 | # C file 58 | echo "// Copyright (c) 2021 Microsoft Corporation." 59 | echo "" 60 | echo '#include "stdafx.h"' 61 | echo "" 62 | echo -n "const GUID SYSMON_PROVIDER = " 63 | echo -n `grep 'SYSMON_PROVIDER' $SYSMONMSGOP | sed -e 's/^.*guid="{\(.\{8\}\)-\(....\)-\(....\)-\(..\)\(..\)-\(..\)\(..\)\(..\)\(..\).*$/{0x\1, 0x\2, 0x\3, {0x\4, 0x\5, 0x\6, 0x\7, 0x\8, 0x\9, /'` 64 | echo `grep 'SYSMON_PROVIDER' $SYSMONMSGOP | sed -e 's/^.*guid="{.\{8\}-....-....-....-.\{8\}\(..\)\(..\).*$/0x\1, 0x\2}};/'` 65 | echo "" 66 | grep ' 26 | #include 27 | #include 28 | 29 | //-------------------------------------------------------------------- 30 | // 31 | // hexdump 32 | // 33 | // Dump n bytes of the provided buffer as hex unsigned chars to stdout 34 | // 35 | //-------------------------------------------------------------------- 36 | void hexdump(const unsigned char *x, size_t n) 37 | { 38 | if (x == NULL) { 39 | fprintf(stderr, "hexdump invalid params\n"); 40 | return; 41 | } 42 | 43 | printf("\n"); 44 | for (size_t i=0; i 26 | 27 | void hexdump(const char *x, size_t n); 28 | 29 | -------------------------------------------------------------------------------- /installer.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // installer.h 20 | // 21 | // Functions that install Sysmon For Linux 22 | // 23 | //==================================================================== 24 | 25 | #include 26 | 27 | bool installFiles(bool force); 28 | bool copyConfigFile(const char *configFile); 29 | bool createEmptyConfigFile(); 30 | bool writeArgv(int argc, char *argv[]); 31 | bool readArgv(int *argc, char ***argv, char **configFile); 32 | char *GetCommandLine(); 33 | bool writeFieldSizes(char *fieldSizesStr); 34 | char *readFieldSizes(); 35 | bool setRunState(unsigned int runState, bool running); 36 | bool stopSysmonService(); 37 | bool startSysmonService(); 38 | bool sysmonSearch(int signal); 39 | void killOtherSysmon(bool force); 40 | bool sysmonIsRunning(); 41 | void signalConfigChange(); 42 | bool displayConfig(); 43 | void uninstall(); 44 | 45 | -------------------------------------------------------------------------------- /linuxHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // linuxHelpers.h 20 | // 21 | // Functions exported by linuxHelpers.cpp 22 | // 23 | //==================================================================== 24 | 25 | #include 26 | #include 27 | #include "linuxTypes.h" 28 | #include "ioctlcmd.h" 29 | 30 | typedef pthread_mutex_t CRITICAL_SECTION; 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | void InitializeCriticalSection( CRITICAL_SECTION *p ); 37 | void EnterCriticalSection( CRITICAL_SECTION* p ); 38 | bool TryEnterCriticalSection( CRITICAL_SECTION* p ); 39 | void LeaveCriticalSection( CRITICAL_SECTION* p ); 40 | void DeleteCriticalSection( CRITICAL_SECTION *p ); 41 | BOOLEAN GetProcess( PSYSMON_EVENT_HEADER Process, size_t Len, ULONG ProcessId ); 42 | void SetBootTime(); 43 | BOOLEAN GetProcessInfo( LONGLONG* StartTime, ULONG* Pts, ULONG* Ppid, ULONG* Sessionid, ULONGLONG* ProcessKey, ULONG Pid ); 44 | BOOLEAN GetProcessName( char* ProcName, unsigned int Len, pid_t Pid ); 45 | BOOLEAN StrIsNum( const char* s ); 46 | BOOLEAN EnumProcesses( DWORD *lpidProcess, DWORD cb, PDWORD lpcbNeeded ); 47 | int StringFromGUID2( const GUID guid, PCHAR lpsz, int cchMax ); 48 | LARGE_INTEGER GetLogonTime( CONST LUID* user_luid ); 49 | VOID EventDataDescCreate( _In_ PEVENT_DATA_DESCRIPTOR EventDataDescriptor, 50 | _In_ const PVOID DataPtr, _In_ ULONG DataSize ); 51 | VOID GetSystemTimeAsLargeInteger( PLARGE_INTEGER timestamp ); 52 | time_t LargeTimeToSeconds( CONST PLARGE_INTEGER timestamp ); 53 | unsigned int LargeTimeMilliseconds( CONST PLARGE_INTEGER timestamp ); 54 | unsigned int LargeTimeNanoseconds( CONST PLARGE_INTEGER timestamp ); 55 | VOID LinuxFileTimeToLargeInteger( PLARGE_INTEGER timestamp, const my_statx_timestamp *filetime ); 56 | VOID LargeIntegerToSystemTimeString( char *s, size_t sLen, CONST PLARGE_INTEGER timestamp ); 57 | void LinuxGetFileHash(uint32_t hashType, PTCHAR imagePath, char *stringBuffer, size_t stringBufferSize); 58 | pid_t GetTid(); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /linuxVersion.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // linuxVersion.h 20 | // 21 | // Version information, specific to the Linux version. 22 | // 23 | //==================================================================== 24 | 25 | // 26 | // Version information 27 | // 28 | #define STRFILEVER "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@" 29 | 30 | // 31 | // File information 32 | // 33 | #define VER_COMPANY "Sysinternals - www.sysinternals.com" 34 | 35 | #define VER_COPYRIGHT "By Mark Russinovich, Thomas Garnier and Kevin Sheldrake\nCopyright (C) 2014-2025 Microsoft Corporation\nLicensed under MIT/GPLv2\nUsing libxml2. libxml2 is Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved." 36 | 37 | -------------------------------------------------------------------------------- /linuxWideChar.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // linuxWideChar.h 20 | // 21 | // Functions exported by linuxWideChar.c 22 | // 23 | //==================================================================== 24 | 25 | #include "linuxTypes.h" 26 | 27 | // 28 | // In linuxWideChar.cpp 29 | // 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | size_t UTF8toUTF16( PWCHAR dst, CONST CHAR* src, size_t len); 35 | size_t UTF16toUTF8( PCHAR dst, CONST WCHAR* src, size_t len); 36 | int WideStrcmp( _In_ PCWCHAR s1, _In_ PCWCHAR s2 ); 37 | int WideStrncmp( _In_ PCWCHAR s1, _In_ PCWCHAR s2, _In_ int n ); 38 | int WideStrcasecmp( _In_ PCWCHAR s1, _In_ PCWCHAR s2 ); 39 | int WideStrncasecmp( _In_ PCWCHAR s1, _In_ PCWCHAR s2, _In_ int n ); 40 | size_t WideStrlen( _In_ PCWCHAR s ); 41 | PCWCHAR WideStrchr( _In_ PCWCHAR s, _In_ CONST WCHAR c ); 42 | PWCHAR WideStrrchr( _In_ PWCHAR s, _In_ CONST WCHAR c ); 43 | PWCHAR WideStrstr( _In_ PWCHAR h, _In_ PCWCHAR n); 44 | size_t WideStrspn( _In_ PCWCHAR s, _In_ PCWCHAR acc ); 45 | WCHAR WideToupper( WCHAR c ); 46 | WCHAR WideTolower( WCHAR c ); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /makePackages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # SysmonForLinux 4 | # 5 | # Copyright (c) Microsoft Corporation 6 | # 7 | # All rights reserved. 8 | # 9 | # MIT License 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | # 17 | 18 | ################################################################################# 19 | # 20 | # makePackages.sh 21 | # 22 | # Builds the directory trees for DEB and RPM packages and, if suitable tools are 23 | # available, builds the actual packages too. 24 | # 25 | ################################################################################# 26 | 27 | 28 | if [ "$5" = "" ]; then 29 | echo "Usage: $0 " 30 | exit 1 31 | fi 32 | 33 | # copy cmake vars 34 | CMAKE_SOURCE_DIR=$1 35 | PROJECT_BINARY_DIR=$2 36 | PACKAGE_NAME=$3 37 | PACKAGE_VER=$4 38 | PACKAGE_REL=$5 39 | PACKAGE_TYPE=$6 40 | 41 | DEB_PACKAGE_NAME="${PACKAGE_NAME}_${PACKAGE_VER}_amd64" 42 | RPM_PACKAGE_NAME="${PACKAGE_NAME}-${PACKAGE_VER}-${PACKAGE_REL}" 43 | 44 | if [ "$PACKAGE_TYPE" = "deb" ]; then 45 | DPKGDEB=`which dpkg-deb` 46 | 47 | # clean up first 48 | if [ -d "${PROJECT_BINARY_DIR}/deb" ]; then 49 | rm -rf "${PROJECT_BINARY_DIR}/deb" 50 | fi 51 | 52 | # copy deb files 53 | mkdir -p "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}" 54 | cp -a "${CMAKE_SOURCE_DIR}/package/DEBIAN" "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/" 55 | cp "${PROJECT_BINARY_DIR}/DEBIANcontrol" "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/DEBIAN/control" 56 | mkdir -p "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/usr/share/man/man8" 57 | cp -a "${PROJECT_BINARY_DIR}/sysmon.8.gz" "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/usr/share/man/man8" 58 | mkdir -p "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/usr/bin" 59 | cp "${PROJECT_BINARY_DIR}/sysmon" "${PROJECT_BINARY_DIR}/deb/${DEB_PACKAGE_NAME}/usr/bin/" 60 | 61 | # make the deb 62 | if [ "$DPKGDEB" != "" ]; then 63 | cd "${PROJECT_BINARY_DIR}/deb" 64 | "$DPKGDEB" -Zxz --build --root-owner-group "${DEB_PACKAGE_NAME}" 65 | RET=$? 66 | else 67 | echo "No dpkg-deb found" 68 | RET=1 69 | fi 70 | 71 | exit 0 72 | fi 73 | 74 | if [ "$PACKAGE_TYPE" = "rpm" ]; then 75 | RPMBUILD=`which rpmbuild` 76 | 77 | if [ -d "${PROJECT_BINARY_DIR}/rpm" ]; then 78 | rm -rf "${PROJECT_BINARY_DIR}/rpm" 79 | fi 80 | 81 | # copy rpm files 82 | mkdir -p "${PROJECT_BINARY_DIR}/rpm/${RPM_PACKAGE_NAME}/SPECS" 83 | cp -a "${PROJECT_BINARY_DIR}/SPECS.spec" "${PROJECT_BINARY_DIR}/rpm/${RPM_PACKAGE_NAME}/SPECS/${RPM_PACKAGE_NAME}.spec" 84 | mkdir "${PROJECT_BINARY_DIR}/rpm/${RPM_PACKAGE_NAME}/BUILD/" 85 | cp "${PROJECT_BINARY_DIR}/sysmon.8.gz" "${PROJECT_BINARY_DIR}/sysmon" "${PROJECT_BINARY_DIR}/rpm/${RPM_PACKAGE_NAME}/BUILD/" 86 | 87 | # make the rpm 88 | if [ "$RPMBUILD" != "" ]; then 89 | cd "${PROJECT_BINARY_DIR}/rpm/${RPM_PACKAGE_NAME}" 90 | "$RPMBUILD" --define "_topdir `pwd`" -v -bb "SPECS/${RPM_PACKAGE_NAME}.spec" 91 | RET=$? 92 | cp RPMS/x86_64/*.rpm .. 93 | else 94 | echo "No rpmbuild found" 95 | RET=1 96 | fi 97 | fi 98 | 99 | exit $RET 100 | -------------------------------------------------------------------------------- /missingdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // missingdefs.h 20 | // 21 | // Defines types that are not available in vmlinux.h 22 | // 23 | // Unfortunately, today, when including vmlinux.h there is no way to 24 | // prevent redefinitions and hence we need to remove all headers that 25 | // cause redefitions. By doing so however, we also miss the defitions 26 | // in those headers that vmlinux.h does not define. This is a known 27 | // problem and the current solution is to define those types seperately. 28 | // This files contains all the defs that are missing. 29 | // 30 | // For more detail, please see: 31 | // https://lore.kernel.org/bpf/CAO658oV9AAcMMbVhjkoq5PtpvbVf41Cd_TBLCORTcf3trtwHfw@mail.gmail.com/ 32 | // 33 | //==================================================================== 34 | 35 | #pragma once 36 | 37 | // If we're not compiling eBPF programs, the below will not be defined. 38 | #ifndef EBPF_CO_RE 39 | enum { 40 | TCP_ESTABLISHED = 1, 41 | TCP_SYN_SENT = 2, 42 | TCP_SYN_RECV = 3, 43 | TCP_FIN_WAIT1 = 4, 44 | TCP_FIN_WAIT2 = 5, 45 | TCP_TIME_WAIT = 6, 46 | TCP_CLOSE = 7, 47 | TCP_CLOSE_WAIT = 8, 48 | TCP_LAST_ACK = 9, 49 | TCP_LISTEN = 10, 50 | TCP_CLOSING = 11, 51 | TCP_NEW_SYN_RECV = 12 52 | }; 53 | #endif 54 | 55 | #ifndef AT_FDCWD 56 | #define AT_FDCWD -100 57 | #endif 58 | 59 | #ifndef AT_REMOVEDIR 60 | #define AT_REMOVEDIR 0x200 61 | #endif 62 | 63 | #ifndef O_CREAT 64 | #define O_CREAT 0100 65 | #endif 66 | 67 | #ifndef PTRACE_ATTACH 68 | #define PTRACE_ATTACH 16 69 | #endif 70 | 71 | #ifndef PTRACE_SEIZE 72 | #define PTRACE_SEIZE 0x4206 73 | #endif -------------------------------------------------------------------------------- /outputxml.h: -------------------------------------------------------------------------------- 1 | /* 2 | SysmonForLinux 3 | 4 | Copyright (c) Microsoft Corporation 5 | 6 | All rights reserved. 7 | 8 | MIT License 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | //==================================================================== 18 | // 19 | // outputxml.h 20 | // 21 | // Functions exported by outputxml.c 22 | // 23 | //==================================================================== 24 | 25 | #ifndef _OUTPUTXML_H 26 | #define _OUTPUTXML_H 27 | 28 | #include "linuxTypes.h" 29 | #include "sysmonevents.h" 30 | 31 | VOID FormatSyslogString( 32 | PCHAR EventStr, 33 | size_t EventMax, 34 | CONST PSYSMON_EVENT_TYPE_FMT EventType, 35 | CONST EVENT_DATA_DESCRIPTOR* Fields, 36 | unsigned int FieldCount 37 | ); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /package/DEBIAN.in/control.in: -------------------------------------------------------------------------------- 1 | Package: sysmonforlinux 2 | Version: @PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@ 3 | Architecture: amd64 4 | Maintainer: Sysinternals 5 | Description: A system monitor based on eBPF, ported from Windows, that outputs events to Syslog 6 | Depends: libc6 (>= 2.14), libgcc1 (>= 1:3.0), libstdc++6 (>= 5), libxml2 (>= 2.7.4), libssl-dev, sysinternalsebpf (>= 1.5.0) 7 | Installed-Size: 58934 8 | 9 | -------------------------------------------------------------------------------- /package/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -f "/tmp/sysmon_config.xml" ]; then 4 | /bin/sysmon -i /tmp/sysmon_config.xml 5 | rm -rf /tmp/sysmon_config.xml 6 | fi -------------------------------------------------------------------------------- /package/DEBIAN/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -d /opt/sysmon ]; then rm -rf /opt/sysmon; fi 4 | 5 | -------------------------------------------------------------------------------- /package/DEBIAN/preinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -f "/opt/sysmon/config.xml" ]; then 4 | cp "/opt/sysmon/config.xml" "/tmp/sysmon_config.xml" 5 | fi 6 | 7 | exit 0 -------------------------------------------------------------------------------- /package/DEBIAN/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sysmon -u 4 | 5 | -------------------------------------------------------------------------------- /package/SPECS.in/spec.in: -------------------------------------------------------------------------------- 1 | Name: sysmonforlinux 2 | Version: @PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@ 3 | Release: @PROJECT_VERSION_TWEAK@%{?dist} 4 | Summary: A system monitor based on eBPF, ported from Windows, that outputs events to Syslog 5 | 6 | License: MIT/GPL2 7 | URL: https://github.com/Sysinternals 8 | 9 | %description 10 | A system monitor based on eBPF, ported from Windows, that outputs events to Syslog 11 | 12 | %install 13 | rm -rf $RPM_BUILD_ROOT 14 | mkdir -p $RPM_BUILD_ROOT/%{_bindir} 15 | cp sysmon $RPM_BUILD_ROOT/%{_bindir} 16 | mkdir -p $RPM_BUILD_ROOT/usr/share/man/man8 17 | cp sysmon.8.gz $RPM_BUILD_ROOT/usr/share/man/man8 18 | 19 | %clean 20 | rm -rf $RPM_BUILD_ROOT 21 | 22 | %files 23 | %{_bindir}/sysmon 24 | /usr/share/man/man8/sysmon.8.gz 25 | 26 | %pre 27 | if [ -f /opt/sysmon/config.xml ]; then 28 | cp /opt/sysmon/config.xml /tmp/sysmon_config.xml 29 | fi 30 | 31 | %post 32 | if [ -d /opt/sysmon ]; then 33 | rm -rf /opt/sysmon 34 | fi 35 | 36 | %posttrans 37 | if [ -f /tmp/sysmon_config.xml ]; then 38 | /bin/sysmon -i /tmp/sysmon_config.xml 39 | rm -rf /tmp/sysmon_config.xml 40 | fi 41 | 42 | %preun 43 | sysmon -u 44 | 45 | %postun 46 | if [ -d /opt/sysmon ]; then rm -rf /opt/sysmon; fi -------------------------------------------------------------------------------- /package/usr/share/man/man8/sysmon_template.8: -------------------------------------------------------------------------------- 1 | .\" Manpage for Sysinternals Sysmon For Linux. 2 | .\" Contact via http://github/Sysinternals to correct errors or typos. 3 | .TH SYSMON 8 "@BUILD_DATE@" "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@" "System Manager's Manual" 4 | 5 | .SH NAME 6 | sysmon \- System Monitor from Sysinternals 7 | 8 | .SH SYNOPSIS 9 | sysmon [options] 10 | 11 | .SH DESCRIPTION 12 | System Monitor (Sysmon) is a system service and set of eBPF programs that, 13 | once installed on a system, remains resident across system reboots to monitor 14 | and log system activity to the Syslog. It provides detailed information about 15 | process creations, network connections, and file creations and deletions. By 16 | collecting the events it generates using SIEM agents and subsequently analyzing 17 | them, you can identify malicious or anomalous activity and understand how 18 | intruders and malware operate on your network. 19 | 20 | Note that Sysmon does not provide analysis of the events it generates, nor does 21 | it attempt to protect or hide itself from attackers. 22 | 23 | Sysmon includes the following capabilities: 24 | 25 | .IP \[bu] 2 26 | Logs process creation with full command line for both current and parent 27 | processes. 28 | .IP \[bu] 29 | Includes a process GUID in process create events to allow for correlation of 30 | events even when Linux reuses process IDs. 31 | .IP \[bu] 32 | Includes a session GUID in each event to allow correlation of events on same 33 | logon session. 34 | .IP \[bu] 35 | Logs file creations and deletions. 36 | .IP \[bu] 37 | Logs opens for raw read access of disks and volumes. 38 | .IP \[bu] 39 | Optionally logs network connections, including each connection’s source 40 | process, IP addresses and port numbers. 41 | .IP \[bu] 42 | Logs ptrace (process access) activity. 43 | .IP \[bu] 44 | Rule filtering to include or exclude certain events dynamically. 45 | 46 | .PP 47 | Events are stored in the Syslog, often found at /var/log/syslog. 48 | 49 | Use the '\-? config' command for configuration file documentation. More 50 | examples are available on the Sysinternals website. 51 | 52 | Neither install nor uninstall requires a reboot. 53 | 54 | .SH OPTIONS 55 | \-c [config] Update configuration of an installed Sysmon driver or dump the 56 | current configuration if no other argument is provided. Optionally 57 | take a configuration file. 58 | \-i [config] Install service and driver. Optionally take a configuration file. 59 | \-s Print configuration schema definition of the specified version. 60 | Specify 'all' to dump all schema versions (default is latest)). 61 | \-u Uninstall service and driver. Adding force causes uninstall to proceed 62 | even when some components are not installed. 63 | \-btf Uses the specified offline BTF file. 64 | \-? Help. 65 | \-? config Configuration help. 66 | 67 | .SH SEE ALSO 68 | ps(1), perf(1), top(1), procmon(1), procdump(1) 69 | 70 | .SH BUGS 71 | No known bugs. 72 | 73 | .SH NOTES 74 | File paths are typically constructed in eBPF by traversing the file system. 75 | It is possible that system limits will in some cases prevent the full path 76 | from being recovered. In this situations, the first character of the path will 77 | be a '+' to indicate that more directories may have preceded it. 78 | 79 | .SH AUTHOR 80 | Sysinternals - www.sysinternals.com 81 | 82 | Mark Russinovich, Thomas Garnier and Kevin Sheldrake 83 | 84 | Copyright (C) 2014-2025 Microsoft Corporation 85 | 86 | .SH COPYRIGHT 87 | The userland part of Sysmon is licensed under MIT; the eBPF parts are licensed 88 | under GPL2. 89 | 90 | 91 | -------------------------------------------------------------------------------- /perftest/TracepointComparisons.md: -------------------------------------------------------------------------------- 1 | # Tracepoint Comparisons 2 | 3 | ## Introduction 4 | 5 | As explained in the documentation, there are three ways of attaching to syscall 6 | tracepoints: 7 | 8 | * Connect as raw tracepoint to raw\_syscalls tracepoints on enter and exit of 9 | entire syscall architecture. This is what Sysmon For Linux does. 10 | * Connect as traditional tracepoint to raw\_syscalls tracepoints. 11 | * Connect to individual traditional tracepoints on enter and exit of each 12 | syscall. 13 | 14 | Sysmon For Linux connects to raw tracepoints as eBPF documentation implied 15 | that this would provide better performance. 16 | 17 | ## Results 18 | 19 | ![Performance graph](sysmonPerf.png) 20 | 21 | The graph shows that the performance of the three approaches are very similar. 22 | Statistical analysis (a robust linear regression model with planned contrasts) 23 | revealed that the differences between them were not statistically significant. 24 | 25 | Raw data is in perfSysmon.csv. 26 | 27 | -------------------------------------------------------------------------------- /perftest/perf.csv: -------------------------------------------------------------------------------- 1 | test,exec_per_sec,cpu 2 | noaudit,100,0 3 | noaudit,200,0 4 | noaudit,400,0 5 | noaudit,800,0 6 | noaudit,1600,0 7 | auditdNoRules,100,0 8 | auditdNoRules,200,0 9 | auditdNoRules,400,0 10 | auditdNoRules,800,0 11 | auditdNoRules,1600,0 12 | auditdraw,100,4.54 13 | auditdraw,200,7.84 14 | auditdraw,400,14.07 15 | auditdraw,800,20 16 | auditdraw,1600,29.53 17 | auditdenriched,100,5.51 18 | auditdenriched,200,9.34 19 | auditdenriched,400,15.46 20 | auditdenriched,800,24.26 21 | auditdenriched,1600,35.67 22 | go-audit,100,5.2 23 | go-audit,200,7.81 24 | go-audit,400,14.5 25 | go-audit,800,21.2 26 | go-audit,1600,32.14 27 | auditbeat,100,9.7 28 | auditbeat,200,17.2 29 | auditbeat,400,27.91 30 | auditbeat,800,40.03 31 | auditbeat,1600,55.95 32 | sysmon,100,4.64 33 | sysmon,200,7.2 34 | sysmon,400,11.08 35 | sysmon,800,18.52 36 | sysmon,1600,27.55 37 | laurel,100,7 38 | laurel,200,11.38 39 | laurel,400,18.57 40 | laurel,800,30.44 41 | laurel,1600,44.17 42 | -------------------------------------------------------------------------------- /perftest/perf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/SysmonForLinux/412cb37d80591d8fb1bc4852578928ae36554d7b/perftest/perf.png -------------------------------------------------------------------------------- /perftest/perf2.csv: -------------------------------------------------------------------------------- 1 | test,exec_per_sec,cpu 2 | noaudit,100,0 3 | noaudit,200,0 4 | noaudit,400,0 5 | noaudit,800,0 6 | noaudit,1600,0 7 | auditdNoRules,100,0 8 | auditdNoRules,200,0 9 | auditdNoRules,400,0 10 | auditdNoRules,800,0 11 | auditdNoRules,1600,0 12 | auditdraw,100,1.4 13 | auditdraw,200,2.47 14 | auditdraw,400,4.06 15 | auditdraw,800,5.56 16 | auditdraw,1600,8.53 17 | auditdenriched,100,2.27 18 | auditdenriched,200,4.1 19 | auditdenriched,400,6.6 20 | auditdenriched,800,9.47 21 | auditdenriched,1600,14.3 22 | go-audit,100,1.4 23 | go-audit,200,2.7 24 | go-audit,400,4.74 25 | go-audit,800,6.56 26 | go-audit,1600,8.3 27 | auditbeat,100,6.07 28 | auditbeat,200,12.3 29 | auditbeat,400,19.1 30 | auditbeat,800,28.27 31 | auditbeat,1600,42.1 32 | sysmon,100,4.43 33 | sysmon,200,6.8 34 | sysmon,400,10.62 35 | sysmon,800,16.67 36 | sysmon,1600,24.71 37 | laurel,100,3.44 38 | laurel,200,5.9 39 | laurel,400,11.36 40 | laurel,800,17.24 41 | laurel,1600,24.9 42 | -------------------------------------------------------------------------------- /perftest/perf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/SysmonForLinux/412cb37d80591d8fb1bc4852578928ae36554d7b/perftest/perf2.png -------------------------------------------------------------------------------- /perftest/sysmonPerf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/SysmonForLinux/412cb37d80591d8fb1bc4852578928ae36554d7b/perftest/sysmonPerf.png -------------------------------------------------------------------------------- /perftest/tests/audit.rules: -------------------------------------------------------------------------------- 1 | ## First rule - delete all 2 | -D 3 | 4 | ## Increase the buffers to survive stress events. 5 | ## Make this bigger for busy systems 6 | -b 8192 7 | 8 | ## This determine how long to wait in burst of events 9 | --backlog_wait_time 0 10 | 11 | ## Set failure mode to syslog 12 | -f 1 13 | 14 | -a always,exit -F arch=b64 -S execve,execveat 15 | -------------------------------------------------------------------------------- /perftest/tests/auditbeat.rules: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b64 -S execve,execveat 2 | -------------------------------------------------------------------------------- /perftest/tests/auditdenriched.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This file controls the configuration of the audit daemon 3 | # 4 | 5 | local_events = yes 6 | write_logs = yes 7 | log_file = /var/log/audit/audit.log 8 | log_group = adm 9 | log_format = ENRICHED 10 | flush = INCREMENTAL_ASYNC 11 | freq = 50 12 | max_log_file = 8 13 | num_logs = 5 14 | priority_boost = 4 15 | disp_qos = lossy 16 | dispatcher = /sbin/audispd 17 | name_format = NONE 18 | ##name = mydomain 19 | max_log_file_action = ROTATE 20 | space_left = 75 21 | space_left_action = SYSLOG 22 | verify_email = yes 23 | action_mail_acct = root 24 | admin_space_left = 50 25 | admin_space_left_action = SUSPEND 26 | disk_full_action = SUSPEND 27 | disk_error_action = SUSPEND 28 | use_libwrap = yes 29 | ##tcp_listen_port = 60 30 | tcp_listen_queue = 5 31 | tcp_max_per_addr = 1 32 | ##tcp_client_ports = 1024-65535 33 | tcp_client_max_idle = 0 34 | enable_krb5 = no 35 | krb5_principal = auditd 36 | ##krb5_key_file = /etc/audit/audit.key 37 | distribute_network = no 38 | -------------------------------------------------------------------------------- /perftest/tests/auditdlaurel.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This file controls the configuration of the audit daemon 3 | # 4 | 5 | local_events = yes 6 | write_logs = no 7 | log_file = /var/log/audit/audit.log 8 | log_group = adm 9 | log_format = RAW 10 | flush = INCREMENTAL_ASYNC 11 | freq = 50 12 | max_log_file = 8 13 | num_logs = 5 14 | priority_boost = 4 15 | disp_qos = lossy 16 | dispatcher = /sbin/audispd 17 | name_format = NONE 18 | ##name = mydomain 19 | max_log_file_action = ROTATE 20 | space_left = 75 21 | space_left_action = SYSLOG 22 | verify_email = yes 23 | action_mail_acct = root 24 | admin_space_left = 50 25 | admin_space_left_action = SUSPEND 26 | disk_full_action = SUSPEND 27 | disk_error_action = SUSPEND 28 | use_libwrap = yes 29 | ##tcp_listen_port = 60 30 | tcp_listen_queue = 5 31 | tcp_max_per_addr = 1 32 | ##tcp_client_ports = 1024-65535 33 | tcp_client_max_idle = 0 34 | enable_krb5 = no 35 | krb5_principal = auditd 36 | ##krb5_key_file = /etc/audit/audit.key 37 | distribute_network = no 38 | -------------------------------------------------------------------------------- /perftest/tests/auditdraw.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This file controls the configuration of the audit daemon 3 | # 4 | 5 | local_events = yes 6 | write_logs = yes 7 | log_file = /var/log/audit/audit.log 8 | log_group = adm 9 | log_format = RAW 10 | flush = INCREMENTAL_ASYNC 11 | freq = 50 12 | max_log_file = 8 13 | num_logs = 5 14 | priority_boost = 4 15 | disp_qos = lossy 16 | dispatcher = /sbin/audispd 17 | name_format = NONE 18 | ##name = mydomain 19 | max_log_file_action = ROTATE 20 | space_left = 75 21 | space_left_action = SYSLOG 22 | verify_email = yes 23 | action_mail_acct = root 24 | admin_space_left = 50 25 | admin_space_left_action = SUSPEND 26 | disk_full_action = SUSPEND 27 | disk_error_action = SUSPEND 28 | use_libwrap = yes 29 | ##tcp_listen_port = 60 30 | tcp_listen_queue = 5 31 | tcp_max_per_addr = 1 32 | ##tcp_client_ports = 1024-65535 33 | tcp_client_max_idle = 0 34 | enable_krb5 = no 35 | krb5_principal = auditd 36 | ##krb5_key_file = /etc/audit/audit.key 37 | distribute_network = no 38 | -------------------------------------------------------------------------------- /perftest/tests/execPerSec/execPerSec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void usage(char *exe) 7 | { 8 | printf("Usage: %s [