update readme to include new flag -i

This commit is contained in:
Dominic Breuker
2018-03-28 09:39:50 +02:00
parent 8e61b2bd9d
commit 093b9ec69c

View File

@@ -7,12 +7,13 @@
[![Test Coverage](https://api.codeclimate.com/v1/badges/23328b2549a76aa11dd5/test_coverage)](https://codeclimate.com/github/DominicBreuker/pspy/test_coverage)
[![CircleCI](https://circleci.com/gh/DominicBreuker/pspy.svg?style=svg)](https://circleci.com/gh/DominicBreuker/pspy)
pspy is a command line tool designed to snoop on processes without needing root permissions.
pspy is a command line tool designed to snoop on processes without need for root permissions.
It allows you to see commands run by other users, cron jobs, etc. as they execute.
Great for enumeration of linux systems in CTFs.
Great for enumeration of Linux systems in CTFs.
Also great to demonstrate your colleagues why passing secrets as arguments on the command line is a bad idea.
The tool gathers it's info from procfs scans.
Inotify watchers placed on selected parts of the file system trigger these scans to increase the chance of catching short-lived processes.
Inotify watchers placed on selected parts of the file system trigger these scans to catch short-lived processes.
## Getting started
@@ -28,18 +29,22 @@ The summary is as follows:
- -f: enables printing file system events to stdout (disabled by default)
- -r: list of directories to watch with inotify. pspy will watch all subdirectories recursively (by default, watches /usr, /tmp, /etc, /home, /var, and /opt).
- -d: list of directories to watch with inotify. pspy will watch these directories only, not the subdirectories (empty by default).
- -i: interval in milliseconds between procfs scans. pspy scans regularly for new processes regardless of Inotify events, just in case some events are not received.
Default settings should be fine for most applications.
The default settings should be fine for most applications.
Watching files inside `/usr` is most important since many tools will access libraries inside it.
Some more complex examples:
```bash
# print both commands and file system events, but watch only two directories (one recursive, one not)
pspy64 -pf -r /path/to/my/dir -d /path/to/my/other/dir
# print both commands and file system events and scan procfs every 1000 ms (=1sec)
./pspy64 -pf -i 1000
# disable printing commands but enable file system events
pspy64 -p=false -f
# place watchers recursively in two directories and non-recursively into a third
./pspy64 -r /path/to/first/recursive/dir -r /path/to/second/recursive/dir -d /path/to/the/non-recursive/dir
# disable printing discovered commands but enable file system events
./pspy64 -p=false -f
```
### Examples
@@ -47,8 +52,9 @@ pspy64 -p=false -f
### Cron job watching
To see the tool in action, just clone the repo and run `make example` (Docker needed).
The example starts a debian container in which a cron job changes a user password every minute.
After starting cron, it runs pspy in foreground, as user myuser, not root.
It is known passing passwords as command line arguments is not safe, and the example can be used to demonstrate it.
The command starts a Debian container in which a secret cron job, run by root, changes a user password every minute.
pspy run in foreground, as user myuser, and scans for processes.
You should see output similar to this:
```console
@@ -78,49 +84,46 @@ Printing: processes=true file-system events=false
2018/02/18 21:01:01 CMD: UID=8 PID=28 | /usr/sbin/exim4 -Mc 1enW4z-00000Q-Mk
```
First, pspy prints all currently running processes.
It prints PID, UID and the command line.
Each time pspy detects a new PID, it adds a line to this log.
First, pspy prints all currently running processes, each with PID, UID and the command line.
When pspy detects a new process, it adds a line to this log.
In this example, you find a process with PID 23 which seems to change the password of myuser.
This is the result of a Python script used in roots private crontab `/var/spool/cron/crontabs/root`, which executes this shell command (check [crontab](docker/var/spool/cron/crontabs/root) and [script](docker/root/scripts/password_reset.py)).
Note that myuser can neither see the crontab nor the Python script.
With pspy, it can see the commands nevertheless.
### CTF example from Hach The Box
### CTF example from Hack The Box
Below is an example from the machine Shrek from [Hack The Box](https://www.hackthebox.eu/).
In this CTF challenge, the task is to exploit a hidden cron job that's changing ownership of all files in a folder.
With pspy, the cron job is easy to find and analyse:
The vulnerability is the insecure use of a wildcard together with chmod ([details](https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt) for the interested reader).
It requires substantial guesswork to find and exploit it.
With pspy though, the cron job is easy to find and analyse:
![animated demo gif](images/demo.gif)
## How it works
Several tools exist to list all processes executed on Linux systems, including those that have finished.
Tools exist to list all processes executed on Linux systems, including those that have finished.
For instance there is [forkstat](http://smackerelofopinion.blogspot.de/2014/03/forkstat-new-tool-to-trace-process.html).
It receives notifications from the kernel on process-related events such as fork and exec.
Unfortunately, the tool requires root privileges so you cannot use it to right away.
However, nothing stop you in general from snooping on the processes running on the system.
All data is visible as long as the process is running.
These tools require root privileges, but that should not give you a false sense of security.
Nothing stops you from snooping on the processes running on a Linux system.
A lot of information is visible in procfs as long as a process is running.
The only problem is you have to catch short-lived processes in the very short time span in which they are alive.
Scanning the `/proc` directory for new PIDs in an infinite loop does the trick but consumes a lot of CPU.
A stealthier way is to use the following trick.
Process tend to access files such as libraries in `/usr`, temporary files in `/tmp`, log files in `/var`, ...
Without root permissions, you can get notifications whenever these files are touched.
The API for this is called [inotify](http://man7.org/linux/man-pages/man7/inotify.7.html).
While we cannot monitor processes directly, but we can monitor their interactions with the file system.
Using the [inotify](http://man7.org/linux/man-pages/man7/inotify.7.html) API, you can get notifications whenever these files are created, modified, deleted, accessed, etc.
Linux does not require priviledged users for this API since it is needed for many innocent applications (such as text editors showing you an up-to-date file explorer).
Thus, while non-root users cannot monitor processes directly, they can monitor the effects of processes on the file system.
We can use the file system events as a trigger to scan `/proc`, hoping that we can do it fast enough to catch the processes.
This is what pspy does.
Thus, there is no guarantee you won't miss one, but chances seem to be good in my experiments.
There is no guarantee you won't miss one, but chances seem to be good in my experiments.
In general, the longer the processes run, the bigger the chance of catching them is.
Besides using the events, pspy will also scan `/proc` every 100ms, just to be sure.
CPU usage seems to be quite low for this interval.
Making the interval configurable is on the roadmap.
# Misc
Logo: "By Creative Tail [CC BY 4.0 (http://creativecommons.org/licenses/by/4.0)], via Wikimedia Commons" ([link](https://commons.wikimedia.org/wiki/File%3ACreative-Tail-People-spy.svg))