Run PentestGPT on an uncensored model

PentestGPT is an LLM-driven assistant that plans and guides a penetration test. Pointed at a mainstream model it often refuses the work. Point it at Obscurify.ai and a cybersecurity-tuned model, and it answers. You get an account that’s a 16-digit number instead of an email.

Authorized work only. Use this for penetration tests you have written permission for, CTFs, and your own systems. Obscurify.ai’s terms prohibit using it to write or spread malware, or to break into computers, accounts or networks you are not authorized to access. In our test we scanned nothing but a service on 127.0.0.1.

Tested on 2026-11-08 with PentestGPT’s modernized pentestgpt-legacy mode (v1.0.0) against the live API, driving a real Pentesting Task Tree with the heabsy/cyberheabsy model against a local in-scope HTTP server.

Before you start

  • PentestGPT. Install the current version (Python 3.12): uv tool install "git+https://github.com/GreyDGL/PentestGPT". On modern toolchains an old transitive pin can fail to build; install with --override bumping greenlet>=3.1 and playwright>=1.47 if so.
  • An Obscurify.ai API key. Create an account — a random 16-digit number, no email. Add credit on the account page, then click Show API Key. The key starts with sk-obs1_ and can be fetched again from your account number.

Pick a cybersecurity model

These are decensored, cybersecurity-tuned models that work on any funded account (no Pro plan needed), all with tool support. See /v1/models:

  • heabsy/cyberheabsy (used in the test)
  • orca/orcacyber-minimax-m3.1-flash (fast, cheap, 8 of 8 in our security test)

Point PentestGPT at Obscurify.ai

PentestGPT’s --base-url with an ollama:<model> id lets you send an arbitrary model to an OpenAI-compatible endpoint. That path assumes a keyless local server, so put a tiny local shim in front that adds your Obscurify.ai bearer key. Save this as obs_proxy.py:

# Injects the Obscurify.ai key into /v1 requests on 127.0.0.1:8799
import http.server, urllib.request, os
UP="https://obscurify.ai"; KEY=os.environ["OBSCURIFY_API_KEY"]
class H(http.server.BaseHTTPRequestHandler):
    def _f(self,m):
        ln=int(self.headers.get("Content-Length",0)); body=self.rfile.read(ln) if ln else None
        req=urllib.request.Request(UP+self.path,data=body,method=m)
        req.add_header("Authorization","Bearer "+KEY)
        req.add_header("Content-Type",self.headers.get("Content-Type","application/json"))
        try: r=urllib.request.urlopen(req,timeout=180); data,code=r.read(),r.status
        except urllib.error.HTTPError as e: data,code=e.read(),e.code
        self.send_response(code); self.send_header("Content-Type","application/json")
        self.send_header("Content-Length",str(len(data))); self.end_headers(); self.wfile.write(data)
    def do_GET(self): self._f("GET")
    def do_POST(self): self._f("POST")
    def log_message(self,*a): pass
http.server.HTTPServer(("127.0.0.1",8799),H).serve_forever()

Run it, then start PentestGPT against it:

export OBSCURIFY_API_KEY="sk-obs1_..."
python3 obs_proxy.py &

pentestgpt-legacy \
  --reasoning-model ollama:heabsy/cyberheabsy \
  --parsing-model  ollama:heabsy/cyberheabsy \
  --base-url http://127.0.0.1:8799/v1

When it asks for the task, describe your authorized, in-scope target in one line (including the target IP). PentestGPT builds a Pentesting Task Tree and walks you through recon, scanning and next steps, summarizing any tool output you paste back in.

What it costs

Billed from your balance at each model’s price. A planning session is a handful of calls. Paid models have no monthly token limit. See pricing.

If something fails

  • 401 through the proxy: make sure OBSCURIFY_API_KEY is set in the shell that launched obs_proxy.py.
  • 402: no balance — add credit on the account page.
  • 404 model_not_found: check the id against /v1/models and keep its prefix.
  • Install build failure: bump greenlet and playwright with an override as above.

What stays private

Prompts and responses aren’t stored on Obscurify.ai’s servers; models with the ZDR tag run only on zero-data-retention routes. Providers see the prompt text but not who sent it. See the privacy policy.

More: Obscurify.ai for agents.