Skip to content

Terminal based intercepting proxy written in rust with tmux and vim as user interface.

License

Notifications You must be signed in to change notification settings

hail-hydrant/zxc

Repository files navigation

Terminal based intercepting proxy written in rust with tmux and vim as user interface.

Table of Contents
  1. About The Project
  2. Features
  3. Prerequisites
  4. Installation
  5. Usage
  6. Windows
  7. Filetypes
  8. Search
  9. Encoding and Decoding
  10. Configuration
  11. Highlight Groups
  12. Logging
  13. Debugging
  14. Roadmap
  15. Contributing
  16. Social

Screenshots

Interceptor

Interceptor Showq

History with 100k+ entries

History edit host scope

History edit status code scope

History edit uri scope

History show host scope

History show status code scope

History show uri scope

History show filters

History apply filters

Repeater

Repeater websocket

Addons - ffuf

Addons - sqlmap

Edit buffer variables

Edit Local Config in popup

Log

About The Project

The tool requires zxc.vim vim plugin which enables vim to function as a user interface. Each window and filetype has its own set of keybindings and commands.

The following windows are present in zxc:

When zxc is called a list of bash alias is used to spawn vim with specific window name which loads corresponding vim config. All windows are vim instances which communicate with zxc binary via unixsocket channel.

Alias Window
interceptor Interceptor
vhistory History
repeater Repeater
addons Addons

The windows (except history which halts recording) can be closed and reopened using their respective aliases.

                        ┌─────────────┐
       ┌───────────────►│  zxc binary │◄────┬───────────────┐
       │                └┬────────────┘     │               │
       │                 │                  │               │
       │                 │    unix socket   │               │
       │                 │                  │               │
┌──────▼──────┐   ┌──────▼──────┐   ┌───────▼─────┐   ┌─────▼──────┐
│ Interceptor │   │   History   │   │   Repeater  │   │  Addons    │
└─────────────┘   └─────────────┘   └─────────────┘   └────────────┘

Features

  • tmux and vim as user interface.
  • Disk based storage.
  • Custom http/1.1 parser to send malformed requests.
  • http/1.1 and websocket support.

Prerequisites

  • getfattr
  • tmux
  • vim (> 8.2.4684) with the following features
    • channel
    • terminal
    • timers
  • ffuf
  • sqlmap
  • column (optional for indenting history files)

Packages

attr tmux vim ffuf sqlmap bsdmainutils

Installation

Requirements

  • cargo msrv 1.86.0
  • make
  • openssl

Packages

make openssl

Make

make

copy the zxc binary from ./target/release to $PATH. Install vim plugin.

Manual Installation

  1. Copy config files
mkdir $HOME/.config/zxc
cp ./config/{alias,config.toml,tmux.conf} $HOME/.config/zxc
  1. Generate private key
openssl genrsa -out $HOME/.config/zxc/private.key 2048
  1. Generate CA certificate using ./mkscripts/CA.cnf as CA config.
openssl req -x509 -new -nodes -key $HOME/.config/zxc/private.key -sha256 -days 1024 -out $HOME/.config/zxc/zxca.crt -extensions v3_req -config ./mkscripts/CA.cnf
  1. Copy vim config
mkdir -p $HOME/.vim/plugin
cp ./config/example/zxc.vim $HOME/.vim/plugin
  1. Copy filetype plugins (optional)
cp -r ./config/example/ftplugin $HOME/.vim
  1. Build zxc or download from release.
cargo b --release

vim plugin

Install zxc.vim plugin.

mkdir -p $HOME/.vim/pack/git-plugins/start/
git clone --depth 1 https://github.com/hail-hydrant/zxc.vim $HOME/.vim/pack/git-plugins/start/zxc.vim

Add CA

Add CA certificate from $HOME/.config/zxc/zxca.crt to your trusted CA or browser.

Usage

zxc

Options

  -n, --new-name <NEW_NAME>         Session name to create
  -a, --attach <ATTACH_NAME>        Attach to existing session
  -p, --port <PORT>                 Proxy port to use [default: 8080]
  -i, --include <INCLUDED_DOMAINS>  List of domains to proxy
  -e, --exclude <EXCLUDED_DOMAINS>  List of domains to relay
      --no-ws                       Relay ws connections
  -d, --debug                       Debug mode
  -h, --help                        Print help

-i and -e are mutually exclusive . The values should be in format domain:port.

For example, to intercept all domains except https://example.com,

zxc -e example.com:443

The flags also support wildcard. For example, to intercept all sub domains of http://*.example.com

zxc -i *.example.com:80

The domains can be comma separated list of values.

zxc -i example.com:80,example.com:443

Windows

Interceptor

Displays intercepted requests and responses. Each request or response is added as buffer.

Command Description
InterToggle Toggle Interception
InterForward Forward current request/response
InterForwardAll Forward all requests and responses in queue
InterForwardWithRes Forward Request + Intercept Response
Showq Show interception queue with their respective scheme and host
DropMsg Drop current request/response

History

Displays the following history files,

  • http history (his)
  • all websocket history (whis)
  • single websocket session history (wsess)

Performs history recording. Closing it halts recording. In case of closing the window accidentally reopen it by calling vhistory to resume recording. If zxc is existed without history window, a state file .history.state is created to resume logging the next time zxc is attached to this session.

Note

Window is non modifiable and read only.

Repeater

Repeater window is used to repeat requests. The original request is copied to a folder named r-$id for http and r-ws-$id for websocket within the specific history folder.

Command Description Availability
RepeaterSend Send Request .req and scratch.wreq
WsEstablish Establish Websocket Connection .req in ws repeater

To repeat a websocket request,

  1. In a websocket request (wreq) file, call WsSendToRepeater.
  2. In repeater window, http request corresponding to the websocket handshake is displayed in top-left.
  3. Call WsEstablish in the request(req) window to establish a websocket connection.
  4. Write the data in scratch.wreq in bottom left and call RepeaterSend to send.

Addons

Addons window is used to run additional tools. The original request is copied to a folder named addons/$addon_prefix-$id.req within the specific history folder with prefix specific to the addon being called. The request is displayed in the top window and a terminal with addon cmd and arguments is displayed in bottom split. Currently, ffuf and sqlmap are available.

Add New Addons

Refer to global config for example addon integration.

1. Defining addon

Define a new table in $HOME/.config/zxc/config.toml file.
The following values(strings) are required:

Key Description
name Name of the binary to be called
prefix Prefix for resulting file used by the addon
request_flag Flag used by the addon to identify the request file
For example, -r for sqlmap and -request for ffuf
http_flag Flag used by the addon to identify http scheme
For example, -request-proto http for ffuf
https_flag Flag used by the addon to identify https scheme
For example, --force-tls for sqlmap
add_flag Additional flags that will be added to the end of the command

Note

If the binary by default uses https, skip http_flag and vice versa.

2. Calling Addon

The addon can be called from request .req file by calling RequestToAddon function

call RequestToAddon("addon_name")

Calling from history .his file, by calling HistoryToAddon function

call HistoryToAddon("addon_name")
3. Define Addon Command

Add command or keymap via the ftplugin for req and his.

Example Command for .req

command RequestToAddon_Name :call RequestToAddon("addon_name")

For .his

command HistoryToAddon_Name :call HistoryToAddon("addon_name")

Example Keymap for .req

nnoremap <silent> <Leader>q :call RequestToAddon("addon_name")

For .his

nnoremap <silent> <Leader>q :call HistoryToAddon("addon_name")

File Types

The following file types are available in zxc.

his [http history]

Command Description
HistoryView View highlighted history
Default keybinding is <CR>
HistoryIndent Indent history
HistoryToRepeater Send to Repeater
HistoryToFuzz Send to Ffuf addon
HistoryToSql Send to Sqlmap addon
ApplyFilters Apply filters
ShowFilters Show filters in popup
Use q to close popup
ClearFilters Clear all filters
AddToHostScope Add host in current line to view scope
ClearHostScope Clear host view scope list
EditHostScope Edit host scope in popup
Supports Vim Regex
To match as regex add prefix /r
ShowHostScope Show host scope in popup
Use q to close popup
AddScode Add Command argument to status code scope
Use 'x' in place of wildcard
Example,
  1xx : shows status code in range 100 - 199
  21x : shows status code in range 210 - 219
ClearScode Clear status code scope
EditScode Edit status code scope in popup
ShowScode Show status code scope in popup
Use q to close popup
AddToUriScope Add uri in current line to view scope
ClearUriScope Clear uri view scope list
EditUriScope Edit uri scope in a popup
Supports Vim Regex
To match as regex add prefix /r
ShowUriScope Show uri scope list in a popup
EditConfig Edit local config in popup
If the config is modified then reloaded automatically
ReloadConfig Manually Reload config
ConcealUri Conceal URI column

Note

  • Vim fold is used to apply filters. Use zR to open all folds.

  • The HistoryIndent command uses the column shell command and can be resource intensive on large files. Use sparingly.

  • HostScope and UriScope support vim regex. Prefix the entry with /r to match as regex. For example to match all subdomains of google.com, /r .*.google.com

Conceal

For his filetype, the URI can be concealed. Set g:conceal variable in .his ftplugin to the number of characters to be concealed. Set the conceallevel in your vimrc to enable this feature.

req [http request]

Command Description
EditBufVar Edit buffer variables in a popup
available in interceptor and repeater windows only
RequestToFuzz Send to Ffuf addon
RequestToRepeater Send to Repeater
RequestToSql Send to Sqlmap addon

Variables

req filetype has specific set of variables which can be modified to customize request handling. EditBufVar command can be used to edit buffer variables in a popup. Save and quit popup to reflect changes. The following variables are available in interceptor and repeater windows.

Variable Type Description
b:host string Host to send request to (ignore port for scheme specific default)
b:scheme string http/https
b:sni string SNI to use in TLS handshake (only when b:scheme is https)
b:update bool Whether request should be updated according to RFC.

Extended Attributes

The following extended attributes are set to the .req filetype for users to identify the destination for a request outside of zxc.

Value Description
user.host Host to which request was sent (ignore port for scheme specific default)
user.http Set to "1" when scheme is http.
for https, ignored.
user.sni Set when scheme is https and host != sni

res [http response]

Only variable b:update available.

whis [All websocket history]

Command Description
ViewWsHistory View highlighted ws flow.
Default binding is <CR>.

wsess [Single websocket session history]

Command Description
ViewWsSessionHistory View highlighted ws req/res in split.
Default binding is <CR>.

wreq [websocket request]

Binary Frames are indicated by 'b' in right corner of status line.

Command Description
WsSendToRepeater Send ws request to Repeater

popup [popup window]

The popup window can be customised by setting g:popup_options with vim's popup_create-arguments option in users zxc.vim file.

Additional Filetypes

FileType Description
wres websocket response
popup popup window

Search

The following commands search and fill their respective lists.

Quickfix-list Location-list Filetypes searched
Greq LGreq .req
Gres LGres .res
Greb LGreb both .req and .res

Encoding and Decoding

The following commands are available in VISUAL mode for encoding and decoding in interceptor and repeater windows.

Command Description
EBase64 Base64 encode
DBase64 Base64 decode
EUrl URL encode
DUrl URL decode
EUrlAll URL encode all characters
DUrlAll URL decode all characters

Note

register x is used to store the selected text.

Configuration

tmux config

tmux.conf is used to set up session aliases. In addition it sources user's tmux.conf file from

  1. $HOME/.tmux.conf
  2. $HOME/.config/tmux/tmux.conf
  3. $XDG_CONFIG_HOME/tmux/tmux.conf

If the tmux.conf is in custom location add the location to zxc's tmux.conf file in $HOME/.config/zxc/tmux.conf

source-file /path/to/tmux.conf

zxc config

There are two types of config files, Global and per session local config. Local config is given preference over global config.

Global

Global Config file is located in $HOME/.config/zxc/config.toml. Default global config

Keys Description Possible Values
excluded_domains List of domains to be relayed string list
excluded_content_types List of content types to be relayed list of:
app, audio, font, img, msg,
model, multipart, txt, video
excluded_extensions List of extensions to be relayed string list
with_ws Whether to proxy websocket requests bool (default true)

Local

Per session config is created in $session/config.toml based on user flags. Only if any flag is used, local config is created. Example local config.

Keys Description Possible Values
included_domains List of domains to proxy string list
excluded_domains List of domains to relay string list
no_ws Whether to relay websocket requests bool (default false)

Note

Include and exclude lists are mutually exclusive. If both lists are present Include list is given preference. Supports wildcard.

Edit Local Config

EditConfig command in history window will open local config file in a popup window. On quitting the window if the file is modified the configuration will be reloaded automatically. If the file is edited outside of history window, call ReloadConfig in history window.

Vim Config

Each window and filetype has its own set of commands. Filetypes can be configured in their respective ftplugin. The commands are further explained in :h zxc.txt.

The following global variables are available

Variables Description
g:popup_options Options passed to vim's popup_create-arguments.
g:timeout The time to wait for a response from zxc when blocking.
Default 5000 ms

Example ftplugin links

Link For
zxc interceptor, repeater, Addons, Encoding, Decoding
his his filetype.
req req filetype.

Highlight Groups

Each filetype has its own set of highlight groups. Use :h zxc-highlight-groups to list available highlight groups. A gist of available highlight groups can be found here.

FileType Highlight Group Help
history zxc-hl-his
req zxc-hl-req
res zxc-hl-res

Logging

The log is written to $session/log.txt. The log can be viewed in tmux popup using tmux command zxcl or bind-key e shortcut.

Note

By default, tmux command-alias of index 1000 is used to store the command. In case of conflict change the index to some unassigned value in $HOME/.config/zxc/tmux.conf.

Debugging

Run zxc with -d flag to enable debugging. The proxy debug info from binary is written to $session/log/proxy.log. The channel log for each window is written to $session/log/$window_chan.log. The windows have the following debug commands.

Command Description
PrintDebug Prints debug info
WriteDebug Writes debug info to a file named $window_debug.log in $session/log directory

Roadmap

  • Configuration based host redirection.
  • Follow redirects in repeater.
  • Nvim support.
  • Socks support.
  • http/2 and http/3 support.

Contributing

Feel free to report issues and PR's. Feature requests are most welcome.

Social

Bluesky Reddit X

About

Terminal based intercepting proxy written in rust with tmux and vim as user interface.

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Languages