Skip to main content
Technical Tutorials

A pentesting phone can infer the subnet. It cannot infer permission.

Nightcrawler makes autonomous mobile penetration testing concrete. Its auto-derived network scope also shows why a device's current subnet cannot define where an AI agent is authorized to act.

Sean McLellan profile photo

Sean McLellan

Lead Architect & Founder

7 min read
A two-panel constructed diagram contrasts Nightcrawler's pinned auto-network path, where the current Wi-Fi network becomes allowed, with a recommended control that combines approved targets and the current network and stops when the network changes.
Constructed diagramConstructed from Nightcrawler commit 4d1ed0f, not product UI or an observed run. The pinned-source panel summarizes the auto-network path; the recommended-control panel shows the approval control.

Nightcrawler is an open-source penetration-testing agent that runs on an Android phone. At the pinned source commit, a local model proposes commands and a separate proxy decides whether to forward them for execution. The separation matters because the sample configuration can derive network scope from the phone's current Wi-Fi connection, while permission to test still comes from an approved engagement.

Before such an agent may act, a team must prove that its effective targets are both approved and present on the observed network. It must also prove that the expected proxy allows an approved case, rejects an excluded case, and stops the run when the network changes. This article follows Nightcrawler's pinned code path, then turns that narrow distinction into a practical acceptance test.

The pinned code path moves from a model proposal to a proxy decision

Nightcrawler's README describes a local 1.2-billion-parameter model that selects a target and produces a command. The documented architecture routes that proposed command through a separate scope proxy before the underlying Kali service.

In scope_proxy.py, the /execute endpoint applies controls in a defined order. It checks the command against destructive-command patterns, asks ScopeValidator to check scope, applies rate limiting and jitter, and then forwards an allowed command to the upstream service. The proxy also logs allowed and blocked decisions.

The pinned ScopeValidator extracts literal IP addresses and CIDR values from a command string. CIDR means an address range written with a prefix length. The validator checks those values against its allowed networks and checks recognized port arguments against the excluded-port set. This source path does not by itself establish that every hostname, argument shape, or target form receives the same check.

The sample config.yaml uses networks: ["auto"] under mission.scope. During proxy initialization, scope_proxy.py reads the IPv4 address and prefix length from wlan0, the phone's internal Wi-Fi interface, and normalizes them into the current network's CIDR range. The proxy then uses that derived range to initialize ScopeValidator, along with excluded hosts and ports.

The network value can also change during a run. The proxy calls its refresh function from both /execute and /scope, with detection limited to once every 30 seconds. If wlan0 now belongs to a different CIDR range, the pinned code replaces the validator's allowed network and updates the automatically excluded gateway and phone addresses.

The sample configuration also contains authorization: "ROE-YYYY-XXX.pdf". That value is stored under the mission, but the pinned proxy initialization shown here does not read it when it builds ScopeValidator, RateLimiter, or the audit logger. A filename in configuration therefore remains separate from the code path that decides which network addresses a command may target.

This source reading does not show that the project author tested without permission. The README requires written permission, and the author said in the Show HN discussion that testing covered four authorized networks, including one corporate network. That comment is an author report. It does not provide independent test evidence for every control or target form.

Network membership only identifies location

A phone can use wlan0 to learn where it is connected. That observation can answer a routing question: which local address range can the phone currently reach? It cannot answer which hosts, services, addresses, or ranges the engagement permits the agent to test.

Those sets often differ. An approved engagement can cover only part of a subnet. The same subnet can include shared infrastructure, third-party equipment, an excluded gateway, or systems outside the engagement. Private-address space also carries no permission by itself.

Nightcrawler's automatic refresh is convenient because it keeps the proxy aligned with the current Wi-Fi network. As a control matter, however, replacing the allowed network after a connection change treats the newly observed range as the new scope input. A team still needs an independent approval input that the runtime cannot enlarge through network discovery.

Effective targets should be approved first and narrowed by the current network

The recommended effective target set is the intersection of two inputs: a signed, current approved target list and the network observed at runtime. The approved list says where the engagement permits action. The observed network can only narrow that list to targets reachable in the present network context.

Use one fail-closed sequence for each session:

  1. Verify the approval signature, validity period, engagement identifier, target entries, exclusions, and content digest. Freeze those values for the session.
  2. Observe the current wlan0 address and CIDR. Intersect the observed network with the frozen approved targets, and do not start if the result is empty.
  3. Configure the expected proxy with only that result. Before each forwarded action, confirm that the approval is current, the target remains in the effective set, and the network identity has not changed.
  4. If the network identity changes, stop the run, deny later actions, and keep the command decisions, approval digest, observed networks, stop reason, and time. A person must review the new network and start a new session with fresh approval.

A reference to an authorization file is useful for traceability. The enforcing proxy still needs the approved target data and its verified identity. The new CIDR must not replace the frozen approved target set during the existing run.

A constructed four-step diagram shows approval targets frozen before the current network is observed, the two sets intersected, and command targets enforced; a network change stops the run and requires fresh approval.
Constructed diagramConstructed recommendation derived from Nightcrawler commit 4d1ed0f, not product UI or an observed run. A network change stops the test rather than replacing the approved target set.

The smallest useful test exercises the exact proxy and the stop condition

Run the acceptance test in a controlled environment with non-production targets and benign requests. First, send one allowed request to one approved test target through the proxy that will govern the real run, and confirm that the proxy forwards it and records the decision. Then send the same benign request to a known out-of-scope test target and confirm that this proxy rejects it, rather than relying on a routing failure or unavailable service.

Finally, simulate a Wi-Fi network change while the session is active. The expected result is a stopped run with subsequent actions denied, not an allowed target range derived from the new network. Preserve the frozen approval digest, both observed network values, the last allowed action, the first denied action, the proxy decision, and the stop reason so a reviewer can reconstruct the boundary test.

This is a narrow network-scope test. The broader AI agent sandbox test covers separate filesystem, command, network, credential, evidence, and fallback paths. A pass here proves only the pinned target and network-change behavior tested through the named proxy.

The access decision depends on permission that network discovery cannot supply

A convenient control may detect where a device is. Permission must define where the device may act. Before an AI pentesting agent receives permission to run, the team must bind a current approved target list to the enforcing proxy, reduce it by the observed network, and prove that a network change stops the session.

Teams can place this test inside the AI workflow security review and use the security review worksheet to record the approved targets, proxy, evidence, and stop condition. BaristaLabs uses that review to help teams test the exact action boundary before access expands. The AI workflow controls guide shows how the same evidence connects to review, monitoring, and rollback after the initial access decision.

Sources

Implementation help

Test the target boundary before the agent acts

BaristaLabs helps teams bind approved targets to the enforcement path, exercise a denied case, and prove that network changes stop the workflow safely.

Best fit for teams evaluating agents that can issue commands, reach network targets, or act through privileged local tools.

Turn this idea into a pilot

Which workflow should go first?

Use the readiness check to compare impact, effort, risk, owner, and next step before booking a call.

  • 3-5 minutes
  • Deterministic score
  • No sensitive data
Check workflow readiness

Practical AI Workflow Notes

Want more practical AI operations ideas?

Get short notes on applying AI inside real small-business workflows — from document handling and customer follow-up to internal reporting, compliance, and automation guardrails.

A useful next step if you’re still exploring and not ready to book a 20-minute AI assessment.

Occasional emails. Practical workflow guidance only. Unsubscribe anytime.