l1ackers
Not marked. Sign in and it follows you. Next: 051: ZAP, driven from a command line

~/tutorials/050-a-proxy-you-install-on-purpose.md

050: A proxy you install on purpose

For three lessons you have read one conversation at a time. The tool of this tier is the one that holds every conversation at once: a proxy you route your traffic through, which records, inspects, and lets you touch each exchange. Everything after this, spiders, scanners, fuzzers, sits on top of this instrument. It is the tier's shell, and learning to think in it is the tier's real skill.

What this lesson is for

The browser has a developer console, and you may already know it. The difference between the console and a testing proxy is the difference between watching and holding. The console shows you the page's own view of its traffic. The proxy sits between you and the site, sees every byte both ways regardless of what the page knows, stores the lot, and, in the next lesson, lets you change a request before it goes and repeat it after it happened. Watching is reading. Holding is testing.

What the reader meets

OWASP ZAP, the Zed Attack Proxy. Free, open source, maintained by a foundation, and the honest first choice because its desktop program and its engine are the same thing wearing different clothes. You will meet Burp later as the same idea in a different hand, and everything you learn here transfers.

The lab for this lesson, proxy and target and their shared wire, stands up from the apparatus page the web lab in a handful of commands, and this lesson's receipts all came from it. The addresses the receipts quote, like 172.31.10.2, are that page's private docker numbers, minted at build time and different on your machine.

Three ways to stand the proxy itself up. The desktop program, from zaproxy.org, is the full experience, browser included. The package manager lane, apt install zaproxy on Kali and Debian family. And the docker lane, which is the one this lesson's receipts came from, because it needs no install at all:

$ docker run -d --name zap --network zapnet \
    -p 127.0.0.1:8090:8080 \
    ghcr.io/zaproxy/zaproxy:stable \
    zap.sh -daemon -host 0.0.0.0 -port 8080 \
    -config api.disablekey=true -config view.mode=attack

-daemon runs the engine with no screen, which is exactly what a proxy should be: quiet infrastructure. The published port, 8090 on your loopback, is the proxy itself, the door you will send traffic through. In the desktop program the same engine sits under the windows, and the windows are just views onto what the daemon already does.

The instrument

A proxy is a man in the middle you invited. Point a client at it and every request travels your box, to the proxy, to the site, and back the same way. The proxy sees both halves of every conversation, the halves from lesson 047, in one place, forever, until you clear it.

curl speaks to a proxy with one flag. This is the entire wiring:

$ curl -x http://127.0.0.1:8090 http://172.31.10.2/login.php

Same request as lesson 047, now routed through ZAP. The page answers as before, because a proxy is invisible to both ends by design. And now the difference: the exchange is recorded. ZAP calls its record the history, and the receipt, read from the engine while writing this lesson, is the proof the proxy saw what the browser would have hidden:

{"messages":[{"rtt":"8","responseBody":"<!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.0 Strict//EN\"...

One request, one entry, response body included, timestamped, stored. Eight requests through the proxy, eight entries in the history. That number, checkable at any moment, is the instrument's first gift: the conversation, held.

Then browse through it, several pages of the lab box, and the second gift arrives without being asked. The proxy is not just recording. It is passively scanning everything it sees, and the alerts it raised on the lab box's login page while writing this lesson:

Session Management Response Identified        Informational
Missing Anti-clickjacking Header             Medium
Content Security Policy (CSP) Header Not Set  Medium
Cookie No HttpOnly Flag                      Low
Cookie without SameSite Attribute            Low
Server Leaks Version Information             Low

Read those with lesson 049's eyes and lesson 045's head. Six findings, produced by browsing, no attack fired, no request modified. Two of them, the cookie flags, are the same class as the bearer token lesson: session cookies shipped without protections, visible only because something held the response headers for you. One, the server version leak, is lesson 047's Server: header read as a finding instead of a sentence. The passive scanner is the first three lessons of this tier, mechanized, and it runs while you read the page like a human.

What it is not, yet: it has sent nothing the browser would not have sent. Every alert so far is a claim about responses you received lawfully. The proxy in this lesson is a recording instrument. The editing instrument, repeat and modify, is where you take the wheel, and that is the next lesson's move, taught on purpose, one step at a time.

Try it

  1. Stand ZAP up by whichever lane fits your box, point one curl request through it at your in-scope lab target, and read the history entry for your own request. You sent it. Now you are reading it. That reversal is the whole instrument in one experience.
  2. Browse your lab target through the proxy, a real browsing session, several pages, and then read the alert list. For each alert, one sentence in your notes: what is it claiming, and which earlier lesson taught you to read that evidence. The passive scanner should hold no surprises by now, which is the point of the order this tier teaches in.
  3. Clear the history, then visit one page with the proxy off and once more with it on. Compare what you can say about the two sessions afterwards. The proxy-off session left you with memory. The proxy-on session left you with evidence, and the difference between those two words is the difference between browsing and testing.
Reveal the answer

The wiring card, every lane in one place, the back page of the instrument:

# daemon via docker, loopback only
docker run -d --name zap -p 127.0.0.1:8090:8080 \
  ghcr.io/zaproxy/zaproxy:stable \
  zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.disablekey=true

# any curl request, through the proxy
curl -x http://127.0.0.1:8090 http://TARGET/path

# a whole browser, through the proxy: system or browser proxy settings
#   host 127.0.0.1  port 8090  type http

# the history count, from the engine
curl -s http://127.0.0.1:8090/JSON/core/view/numberOfMessages/

# the alerts, from the engine
curl -s "http://127.0.0.1:8090/JSON/core/view/alerts/?start=0&count=50"

Two notes the card does not say. The loopback bind on the publish is deliberate and carries lesson 048's fence on your behalf: a proxy bound to all interfaces is an open relay for anyone on your network, and a testing proxy that strangers can route through is a liability you built yourself. Bind it to loopback and the only traffic it will ever hold is yours.

The second is the API's own scope lesson, met while building this lab. ZAP's engine refuses API calls from addresses it does not trust, and the docker lane's port forwarding rewrites your address into one the engine does not recognize, so the JSON calls above may answer refused until the API's permitted addresses include the docker bridge. The fix is one config line, and the experience is the lesson: an instrument that polices its own scope, out of the box, is an instrument designed by people who think like lesson 048. When your own tooling warns you about scope, that is not friction. That is the craft agreeing with itself.

What this lesson does not claim

A proxy does not make traffic legal, and it does not make you invisible. The site sees the same request whether a proxy held it or not, and the fence of lesson 048 applies to every byte the proxy sends exactly as it applied to your curl. What changes is you: you hold every conversation, you can return to any of them, and nothing the browser swallowed is lost anymore. The next lesson takes the wheel.

Not marked. Sign in and it follows you. Next: 051: ZAP, driven from a command line
l1ackers · shell this is a way in, not a requirement
$