pentest-proxy

Pentest temporary-use workflow using yorishiro-proxy as an MITM proxy via CLI

SKILL.md

GitHub

/pentest-proxy

Use yorishiro-proxy as an MITM proxy during penetration testing via CLI. All commands use the yorishiro-proxy client subcommand over Bash.

Prerequisites

  • yorishiro-proxy binary is available on PATH
  • Target application is accessible from the proxy host

CLI Parameter Syntax

Parameters are key=value words; the CLI converts each value using the tool's input schema:

  • Scalars are typed automatically (limit=20 is sent as an integer).
  • Arrays of scalars are comma-separated: tls_passthrough.add='a.example.com,b.example.com'.
  • Dotted keys nest: filter.outliers_only=true, params.flow_id=ID. Only the action-style tools (manage, security, intercept, macro, grpc_schema) take a params object; typed tools such as resend_http and fuzz_http take their fields at the top level.
  • Objects and arrays of objects take JSON, quoted for the shell: positions='[{"path":"raw_query","payloads":["a","b"]}]'. A ' inside the single-quoted JSON is written '\''.
  • key:=<json> sends any JSON value as-is (e.g. key:=null).

Run yorishiro-proxy client --help for the full grammar and yorishiro-proxy docs <tool> for each tool's parameters (no server needed).

1. Server Startup

Check if a server is already running:

yorishiro-proxy client list-servers

If no active server is found, start one:

yorishiro-proxy server -mcp-http-addr 127.0.0.1:9090 &

Verify it is ready:

yorishiro-proxy client query resource=status

2. Start Proxy Listener

yorishiro-proxy client proxy_start listen_addr=127.0.0.1:8080

Configure the target application or browser to use 127.0.0.1:8080 as its HTTP proxy.

3. Install CA Certificate

Export the CA certificate for HTTPS interception:

yorishiro-proxy client query resource=ca_cert

Install the output PEM into the target's trust store.

4. Configure TLS Passthrough (Optional)

Bypass TLS interception for specific upstream hosts (these hosts will NOT be intercepted):

yorishiro-proxy client configure tls_passthrough.add='*.cdn.example.com,static.example.com'

5. Capture Traffic

Send requests through the proxy (e.g., curl, browser, or the target app) and list captured flows:

yorishiro-proxy client query resource=flows limit=20

6. Inspect a Flow

yorishiro-proxy client query flow FLOW_ID
yorishiro-proxy client query messages FLOW_ID

Note: query supports positional args: first arg is resource, second is id.

7. Resend a Request

Replay a recorded HTTP request as-is (the result carries the new flow's stream_id):

yorishiro-proxy client resend_http flow_id=FLOW_ID

Replay with a modification. Any field you pass overrides the recorded one; body_patches edits the recorded body in place:

yorishiro-proxy client resend_http flow_id=FLOW_ID tag=patched \
  body_patches='[{"regex":"user_id=1","replace":"user_id=2"}]'

headers replaces the recorded header list wholesale (it is not merged), so when you change a credential, list every header you want sent. Copy them from query messages FLOW_ID.

There is no compare action. To compare two responses, inspect both flows and diff the status code and body:

yorishiro-proxy client query flow FLOW_ID
yorishiro-proxy client query flow NEW_STREAM_ID

Full parameter reference: yorishiro-proxy docs resend_http. Other protocols use resend_ws, resend_grpc and resend_raw (see yorishiro-proxy docs <tool>).

8. Fuzz a Parameter

fuzz_http is synchronous: it sends every variant, then returns a fuzz_id and per-variant results. Each entry of positions names a field of the recorded request (method, scheme, authority, path, raw_query, body, headers[N].name, headers[N].value) and the payloads to substitute there. A raw_query payload replaces the whole query string:

yorishiro-proxy client fuzz_http flow_id=FLOW_ID \
  positions='[{"path":"raw_query","payloads":["q=test1","q=test2","q=test3"]}]'

Full parameter reference (positions, stop_on_5xx, macro hooks): yorishiro-proxy docs fuzz_http.

Retrieve the results later, or only the outliers (status code, body length or timing that deviates from the baseline):

yorishiro-proxy client query resource=fuzz_jobs
yorishiro-proxy client query resource=fuzz_results fuzz_id=FUZZ_ID
yorishiro-proxy client query resource=fuzz_results fuzz_id=FUZZ_ID filter.outliers_only=true

Drill into a variant with yorishiro-proxy client query flow STREAM_ID, using the variant's stream_id.

9. Export Results

Export flows as HAR for reporting:

yorishiro-proxy client manage action=export_flows params.format=har params.output_path=flows.har

output_path is confined to the server's export directory (server flag -export-dir / YP_EXPORT_DIR, default ~/.yorishiro-proxy/exports/): the relative name above lands there, and the response's output_path is the absolute file path. Absolute paths outside that directory are rejected.

10. Cleanup

Stop the proxy listener and delete flow data:

yorishiro-proxy client proxy_stop
yorishiro-proxy client manage action=delete_flows params.flow_id=FLOW_ID

To delete all flows:

yorishiro-proxy client manage action=delete_flows params.confirm=true

Typical Scenarios

IDOR Detection

  1. Authenticate as User A, browse the target to capture flows:
    yorishiro-proxy client query resource=flows limit=50
    
  2. Identify a flow containing a user-specific resource ID (e.g., /api/users/123/profile) and note its request headers:
    yorishiro-proxy client query messages FLOW_ID
    
  3. Resend the request (still as User A) to confirm the baseline:
    yorishiro-proxy client resend_http flow_id=FLOW_ID tag=idor-user-a
    
  4. Resend the same request with User B's credentials. headers replaces the recorded list, so copy every header from step 2 and change only the credential:
    yorishiro-proxy client resend_http flow_id=FLOW_ID tag=idor-user-b \
      headers='[{"name":"Host","value":"target.example.com"},{"name":"Cookie","value":"session=USER_B_SESSION"},{"name":"Accept","value":"application/json"}]'
    
  5. Compare the two responses (each resend returns its stream_id):
    yorishiro-proxy client query flow USER_A_STREAM_ID
    yorishiro-proxy client query flow USER_B_STREAM_ID
    
  6. If User B's response contains User A's data, an IDOR vulnerability exists.

SQL Injection Testing

  1. Capture a flow containing a parameter of interest:
    yorishiro-proxy client query resource=flows limit=20
    yorishiro-proxy client query messages FLOW_ID
    
  2. Fuzz the parameter. Payloads are sent verbatim, so URL-encode them for the query string; a ' inside the single-quoted shell argument is written '\'':
    yorishiro-proxy client fuzz_http flow_id=FLOW_ID \
      positions='[{"path":"raw_query","payloads":["id=1'\''","id=1%20OR%201=1","id=1;%20DROP%20TABLE--"]}]'
    
    Before sending destructive-shaped payloads such as DROP TABLE to a real target, turn on the SafetyFilter Input destructive-sql preset. It blocks matching variants before they reach upstream. The filter can only be configured when the server boots, from the JSON file passed with yorishiro-proxy server -config FILE:
    {"safety_filter": {"enabled": true, "input": {"rules": [{"preset": "destructive-sql"}]}}}
    
    Check that it is active with yorishiro-proxy client security action=get_safety_filter params:='{}'. The filter is a backstop. It only catches the patterns its preset knows, so prefer non-destructive probes (boolean or time-based) against systems you must not damage.
  3. Surface the variants that deviate from the baseline, then inspect one:
    yorishiro-proxy client query resource=fuzz_results fuzz_id=FUZZ_ID filter.outliers_only=true
    yorishiro-proxy client query flow STREAM_ID
    
  4. Inspect any anomalous responses (e.g., status code changes, error messages, timing differences) to confirm injection points.

Authentication Bypass Testing

  1. Capture an authenticated request flow:
    yorishiro-proxy client query resource=flows limit=20
    
  2. Inspect the flow to identify auth headers/cookies:
    yorishiro-proxy client query messages FLOW_ID
    
  3. Resend it with every header except the credentials (headers replaces the recorded list, so the omitted Authorization / Cookie are not sent):
    yorishiro-proxy client resend_http flow_id=FLOW_ID tag=no-auth \
      headers='[{"name":"Host","value":"target.example.com"},{"name":"Accept","value":"application/json"}]'
    
  4. Compare the authenticated and unauthenticated responses:
    yorishiro-proxy client query flow FLOW_ID
    yorishiro-proxy client query flow NO_AUTH_STREAM_ID
    
  5. If the unauthenticated response still returns protected data, an auth bypass exists.

Quick Reference

Task Command
Docs (offline) yorishiro-proxy docs / yorishiro-proxy docs <topic> — no server needed
Tool parameters yorishiro-proxy docs <tool> (e.g. yorishiro-proxy docs fuzz_http)
List flows yorishiro-proxy client query resource=flows limit=20
Flow detail yorishiro-proxy client query flow ID
Flow messages yorishiro-proxy client query messages ID
Proxy status yorishiro-proxy client query resource=status
Resend yorishiro-proxy client resend_http flow_id=ID
Compare yorishiro-proxy client query flow A and yorishiro-proxy client query flow B, then diff
Fuzz yorishiro-proxy client fuzz_http flow_id=ID positions='[{"path":"raw_query","payloads":["a=1","a=2"]}]'
Fuzz results yorishiro-proxy client query resource=fuzz_results fuzz_id=ID
Fuzz outliers yorishiro-proxy client query resource=fuzz_results fuzz_id=ID filter.outliers_only=true
Export HAR yorishiro-proxy client manage action=export_flows params.format=har params.output_path=FILE
CA cert yorishiro-proxy client query resource=ca_cert
Delete flow yorishiro-proxy client manage action=delete_flows params.flow_id=ID
Delete all yorishiro-proxy client manage action=delete_flows params.confirm=true