diff --git a/README.md b/README.md index 0ae3764..eb8b09f 100644 --- a/README.md +++ b/README.md @@ -8,26 +8,17 @@ Table of Contents * [Overview](#overview) * [Introduction](#introduction) * [Contributing](#contributing) - * [I still like Burp, but Pappy looks interesting, can I use both?](#i-still-like-burp-but-pappy-looks-interesting-can-i-use-both) * [How to Use It](#how-to-use-it) * [Installation](#installation) * [Quickstart](#quickstart) * [Lite Mode](#lite-mode) * [Adding The CA Cert to Your Browser](#adding-the-ca-cert-to-your-browser) - * [Firefox](#firefox) - * [Chrome](#chrome) - * [Safari](#safari) - * [Internet Explorer](#internet-explorer) * [Configuration](#configuration) * [General Console Techniques](#general-console-techniques) - * [Run a shell command](#run-a-shell-command) - * [Running Python Code](#running-python-code) - * [Redirect Output To File](#redirect-output-to-file) * [Generating Pappy's CA Cert](#generating-pappys-ca-cert) * [Browsing Recorded Requests/Responses](#browsing-recorded-requestsresponses) * [Tags](#tags) * [Request IDs](#request-ids) - * [Passing Multiple Request IDs to a Command](#passing-multiple-request-ids-to-a-command) * [Context](#context) * [Filter Strings](#filter-strings) * [List of fields](#list-of-fields) @@ -39,19 +30,14 @@ Table of Contents * [Interceptor](#interceptor) * [Repeater](#repeater) * [Macros](#macros) - * [Generating Macros From Requests](#generating-macros-from-requests) - * [Request Objects](#request-objects) - * [Useful Functions](#useful-functions) * [Intercepting Macros](#intercepting-macros) - * [Enabling/Disabling Intercepting Macros](#enablingdisabling-intercepting-macros) * [Macro Templates](#macro-templates) * [Resubmitting Groups of Requests](#resubmitting-groups-of-requests) * [Logging](#logging) * [Additional Commands and Features](#additional-commands-and-features) - * [Response streaming](#response-streaming) * [Viewing Responses In Browser](#viewing-responses-in-browser) + * [Websockets](#websockets) * [Plugins](#plugins) - * [Should I Write a Plugin or a Macro?](#should-i-write-a-plugin-or-a-macro) * [Global Settings](#global-settings) * [Using an HTTP Proxy](#using-an-http-proxy) * [Using a SOCKS Proxy](#using-a-socks-proxy) @@ -99,12 +85,15 @@ How to Use It Installation ------------ Pappy supports OS X and Linux (sorry Windows). Installation requires `pip` or some other command that can handle a `setup.py` with requirements. Once the requirements are installed, you can check that it installed correctly by running `pappy -l` to start the proxy. + ``` $ git clone --recursive https://github.com/roglew/pappy-proxy.git $ cd pappy-proxy $ pip install . ``` +It is also possible (and encouraged!) to install pappy into a [virtual environment](http://docs.python-guide.org/en/latest/dev/virtualenvs/). After installing into a virtual environment, you will have to enter the virtual environment each time you want to run Pappy. + Quickstart ---------- Pappy projects take up an entire directory. Any generated scripts, exported responses, plugin data, etc. will be placed in the current directory so it's good to give your project a directory of its own. To start a project, do something like: @@ -313,8 +302,9 @@ The following commands can be used to view requests and responses | Command | Aliases | Description | |:--------|:--------|:------------| | `ls [a|]`| list, ls |List requests that are in the current context (see Context section). Has information like the host, target path, and status code. With no arguments, it will print the 25 most recent requests in the current context. If you pass 'a' or 'all' as an argument, it will print all the requests in the current context. If you pass a number "n" as an argument, it will print the n most recent requests in the current context. | -| `sm [p]` | sm, site_map | Print a tree showing the site map. It will display all requests in the current context that did not have a 404 response. This has to go through all of the requests in the current context so it may be slow. If the `p` option is given, it will print the paths as paths rather than as a tree. | | `viq ` | view_request_info, viq | View additional information about requests. Includes the target port, if SSL was used, applied tags, and other information. | -| `vfq ` | view_full_request, vfq, kjq | [V]iew [F]ull Re[Q]uest, prints the full request including headers and data. | +| `sm [p]` | sm, site_map | Print a tree showing the site map. It will display all requests in the current context that did not have a 404 response. This has to go through all of the requests in the current context so it may be slow. If the `p` option is given, it will print the paths as paths rather than as a tree. | +| `viq ` | view_request_info, viq | View additional information about requests. Includes the target port, if SSL was used, applied tags, and other information. | +| `vfq ` | view_full_request, vfq, kjq | [V]iew [F]ull Re[Q]uest, prints the full request including headers and data. If the request is part of a websocket handshake, it will also print the messages sent over the websocket. | | `vbq ` | view_request_bytes, vbq | [V]iew [B]ytes of Re[Q]uest, prints the full request including headers and data without coloring or additional newlines. Use this if you want to write a request to a file. | | `ppq ` | pretty_print_request, ppq | Pretty print a request with a specific format. See the table below for a list of formats. | | `vhq ` | view_request_headers, vhq | [V]iew [H]eaders of a Re[Q]uest. Prints just the headers of a request. | @@ -324,6 +314,7 @@ The following commands can be used to view requests and responses | `pps ` | pretty_print_response, pps | Pretty print a response with a specific format. See the table below for a list of formats. | | `pprm ` | print_params, pprm | Print a summary of the parameters submitted with the request. It will include URL params, POST params, and/or cookies | | `pri [ct] [key(s)]` | param_info, pri | Print a summary of the parameters and values submitted by in-context requests. You can pass in keys to limit which values will be shown. If you also provide `ct` as the first argument, it will include any keys that are passed as arguments. | +| `urls ` | urls | Search the full request and response of the given IDs for urls and prints them. Especially useful with a wildcard (`*`) to find URLs from all history. | | `watch` | watch | Print requests and responses in real time as they pass through the proxy. | Available formats for `ppq` and `pps` commands: @@ -402,6 +393,98 @@ The context is a set of filters that define which requests are considered "activ | `fls` | filter_list, fls | Print the filters that make up the current context | | `filter_prune` | filter_prune | Delete all the requests that aren't in the current context from the data file | +You are also able to save and load contexts. When saving a context you pass the command a name. The context can then be loaded with that name. Whenever you load a context, the current context is saved with the name `_` to make it easier to quickly load a context, view requests, then return to the original context. + +| Command | Aliases | Description | +|:--------|:------------|:---| +| `sc ` | `sc`, `save_context` | Save the current filters with the provided name. | +| `lc ` | `lc`, `load_context` | Load a saved context by its name. | +| `dc ` | `dc`, `delete_context` | Delete a saved context by its name. | +| `cls` | `cls`, `list_contexts` | Show a list of saved contexts and the filters for each of them. | + +Here is an example session demonstrating saving/loading contexts: + +``` +pappy> ls +ID Verb Host Path S-Code Req Len Rsp Len Time Mngl +16 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 10515 0.06 -- +15 GET cdn.sstatic.net /Sites/stackoverflow/img/sprites.svg?... 200 OK 0 8131 0.05 -- +14 GET i.stack.imgur.com /eoNf5.png 403 Forbidden 0 173 0.07 -- +13 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 12919 0.07 -- +12 GET cdn.sstatic.net /img/favicons-sprite16.png?v=4b071e01... 200 OK 0 66460 0.09 -- +11 GET i.stack.imgur.com /xqoqk.png 403 Forbidden 0 173 0.07 -- +10 GET i.stack.imgur.com /6HFc3.png 403 Forbidden 0 173 0.06 -- +9 GET i.stack.imgur.com /tKsDb.png 403 Forbidden 0 173 0.06 -- +8 GET i.stack.imgur.com /5d55j.png 403 Forbidden 0 173 0.08 -- +7 GET cdn.sstatic.net /Js/full-anon.en.js?v=a65ef7e053bb 200 OK 0 116828 0.27 -- +6 GET cdn.sstatic.net /img/share-sprite-new.svg?v=78be252218f3 200 OK 0 34771 0.93 -- +5 GET cdn.sstatic.net /clc/clc.min.js?v=6f49b407ccbc 200 OK 0 6969 0.92 -- +4 GET cdn.sstatic.net /Sites/stackoverflow/all.css?v=40629f... 200 OK 0 476855 0.07 -- +3 GET cdn.sstatic.net /Js/stub.en.js?v=5cc84a62e045 200 OK 0 38661 0.08 -- +2 GET ajax.googleapis.com /ajax/libs/jquery/1.12.4/jquery.min.js 200 OK 0 97163 0.09 -- +1 GET stackoverflow.com / 200 OK 0 244280 0.43 -- +pappy> fbi not_jscss +path nctr "(\.js$|\.css$)" +pappy> fbi not_image +path nctr "(\.png$|\.jpg$|\.gif$)" +pappy> sc clean +Filters saved to clean: + path nctr "(\.js$|\.css$)" + path nctr "(\.png$|\.jpg$|\.gif$)" +pappy> cls +Saved contexts: +clean + path nctr "(\.js$|\.css$)" + path nctr "(\.png$|\.jpg$|\.gif$)" + +pappy> sr +pappy> fls +pappy> f host ct sstatic +pappy> ls +ID Verb Host Path S-Code Req Len Rsp Len Time Mngl +16 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 10515 0.06 -- +15 GET cdn.sstatic.net /Sites/stackoverflow/img/sprites.svg?... 200 OK 0 8131 0.05 -- +13 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 12919 0.07 -- +12 GET cdn.sstatic.net /img/favicons-sprite16.png?v=4b071e01... 200 OK 0 66460 0.09 -- +7 GET cdn.sstatic.net /Js/full-anon.en.js?v=a65ef7e053bb 200 OK 0 116828 0.27 -- +6 GET cdn.sstatic.net /img/share-sprite-new.svg?v=78be252218f3 200 OK 0 34771 0.93 -- +5 GET cdn.sstatic.net /clc/clc.min.js?v=6f49b407ccbc 200 OK 0 6969 0.92 -- +4 GET cdn.sstatic.net /Sites/stackoverflow/all.css?v=40629f... 200 OK 0 476855 0.07 -- +3 GET cdn.sstatic.net /Js/stub.en.js?v=5cc84a62e045 200 OK 0 38661 0.08 -- +pappy> lc clean +Set the context to: + path nctr "(\.js$|\.css$)" + path nctr "(\.png$|\.jpg$|\.gif$)" +pappy> ls +ID Verb Host Path S-Code Req Len Rsp Len Time Mngl +16 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 10515 0.06 -- +15 GET cdn.sstatic.net /Sites/stackoverflow/img/sprites.svg?... 200 OK 0 8131 0.05 -- +13 GET cdn.sstatic.net /img/developer-story/announcement_ban... 200 OK 0 12919 0.07 -- +6 GET cdn.sstatic.net /img/share-sprite-new.svg?v=78be252218f3 200 OK 0 34771 0.93 -- +1 GET stackoverflow.com / 200 OK 0 244280 0.43 -- +pappy> cls +Saved contexts: +_ + host ct sstatic + +clean + path nctr "(\.js$|\.css$)" + path nctr "(\.png$|\.jpg$|\.gif$)" + +pappy> lc _ +Set the context to: + host ct sstatic +pappy> fls +host ct sstatic +pappy> dc clean +pappy> cls +Saved contexts: +_ + path nctr "(\.js$|\.css$)" + path nctr "(\.png$|\.jpg$|\.gif$)" + +``` + Filter Strings -------------- Filter strings define a condition that a request/response pair must pass to be part of the context. Most filter strings have the following format: @@ -497,6 +580,7 @@ A few filters don't conform to the field, comparer, value format. You can still | before | before, bf, b4 | Filters out any request that is not before the given request. Filters out any request without a time. | | after | after, af | Filters out any request that is not before the given request. Filters out any request without a time. | | inv | inf | Inverts a filter string. Anything that matches the filter string will not pass the filter. | +| ws | websocket, ws | Filters out any request that is not part of a websocket connection. | Examples: @@ -935,6 +1019,7 @@ Wrote script to int_headers.py ``` Command information: + | Command | Aliases | Description | |:--------|:--------|:------------| | `gtma