# Cameradar: RTSP camera discovery and dictionary attacks for authorized testing

> Cameradar is a Go tool that scans RTSP endpoints on targets you are authorized to test, identifies the device model, and runs dictionary attacks against stream routes and credentials. It ships as a Docker image or a Go binary, and its defaults are aggressive enough that you should read the configuration before pointing it at a network.

**Ullaakut/cameradar** — Cameradar hacks its way into RTSP videosurveillance cameras

- Repository: https://github.com/Ullaakut/cameradar
- Stars: 5,233 · Forks: 644
- Language: Go
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/ullaakut-cameradar

## What Cameradar does that a generic port scanner does not

A generic scanner tells you port 554 is open. That is not the interesting question with IP cameras. The interesting questions are which device model is behind the port, which stream path it serves, and whether the credentials are still the factory default. Cameradar is built around those three questions. The README lists its capabilities plainly: detect open RTSP hosts on accessible targets, detect the device model that streams the RTSP feed, attempt dictionary-based discovery of stream routes such as /live.sdp, attempt dictionary-based discovery of camera credentials, and produce a report of findings.

The audience is narrow and should stay narrow. This is a penetration testing tool for people who assess video surveillance estates, either their own or a client's under a signed scope. The README devotes a section to security and responsible use, and the flag that matters most for scope control is --targets, which accepts a CIDR, a single IP, a hostname, or a range such as 172.16.100.10-20. If you cannot write the target down as an authorized asset, the tool has nothing to offer you.

## How discovery, route guessing and credential guessing fit together

The pipeline is sequential and each stage feeds the next. Discovery finds candidate hosts and ports. Route discovery then tries dictionary entries against each RTSP endpoint to find a path that returns a stream. Credential discovery tries dictionary entries against the endpoints that responded. The final stage is a report.

The dependency list in go.mod shows what does the work. Discovery leans on github.com/Ullaakut/nmap/v4 and github.com/Ullaakut/masscan, both wrappers around the two well-known scanners. Stream handling uses github.com/bluenviron/gortsplib/v5 and github.com/pion/rtp, so Cameradar speaks RTSP itself rather than shelling out to a media player. The terminal interface is built on the Charm stack (bubbletea, bubbles, lipgloss), and the CLI layer is urfave/cli/v3.

That split matters for how you reason about failures. A port that nmap or masscan cannot see will never reach the RTSP stage, so a filtered network produces empty results that look like a clean estate. The --skip-scan flag exists precisely to break that chain: the README states that if you already know the RTSP endpoints, you can skip discovery and treat each target and port as a stream candidate, which it suggests for restricted networks or a known inventory. In skip-scan mode you are trusting your own inventory instead of the scanner's.

## Installing Cameradar with Docker and running a first scan

Docker is the shortest path and the one the README puts first. The image is ullaakut/cameradar, and the documented invocation uses --net=host so the container can reach the local network directly.

```bash
docker run --rm -t --net=host ullaakut/cameradar --targets 192.168.100.0/24
```

With that command the README says Cameradar scans ports 554, 5554, and 8554 on the target subnet and attempts to enumerate RTSP streams. Note the discrepancy worth knowing before you run it: the configuration section lists a wider default port set of 554, 5554, 8554, http, 322, and 8322, while the quick start names only the first three. If the port set matters to your engagement, set --ports explicitly rather than relying on the default.

If you already know the endpoints and want to skip discovery, the README shows this shape, including the RTSPS certificate handling and the dictionary flags:

```bash
SSL_CERT_FILE=/path/to/ca-or-server.crt \
        cameradar \
        --targets localhost \
        --ports 8322 \
        --skip-scan \
        --custom-routes routes.txt \
        --custom-credentials credentials.json
```

The SSL_CERT_FILE variable is only needed when the stream certificate is self-signed or issued by a private CA and the OS trust store rejects it. For a public CA, the README says no extra setup is needed. If you would rather not use the variable, the alternative it gives is adding your CA certificate to the system trust store used by your runtime environment.

Without Docker, the binary install is one command and requires Go 1.25 or later:

```bash
go install github.com/Ullaakut/cameradar/v6/cmd/cameradar@latest
```

The result lands in $GOPATH/bin. The go.mod file declares go 1.26.7, so the toolchain floor is real; an older Go will not build it.

## Custom dictionaries and the Docker mount that trips people up

The baseline dictionaries live in the repository's dictionaries folder, and the Dockerfile bakes them into the image at /app/dictionaries/routes and /app/dictionaries/credentials.json through the CAMERADAR_CUSTOM_ROUTES and CAMERADAR_CUSTOM_CREDENTIALS environment variables. That is why the quick start works without any volume mounts.

The moment you supply your own wordlists, you have to mount them and pass both flags. The README's example mounts a host directory at /tmp/dictionaries and points the two flags at files inside it:

```bash
docker run --rm -t --net=host \
    -v /path/to/dictionaries:/tmp/dictionaries \
    ullaakut/cameradar \
    --custom-routes /tmp/dictionaries/my_routes \
    --custom-credentials /tmp/dictionaries/my_credentials.json \
    --targets 192.168.100.0/24
```

Two failure modes are easy to hit here. The first is passing only one of the two flags; the README says to pass both. The second is a path mismatch between the mount point and the flag values, which produces a run that silently falls back to whatever the image already has rather than your dictionaries. The Termux instructions in the README show the same pattern with --custom-credentials=/tmp/dictionaries/credentials.json and --custom-routes=/tmp/dictionaries/routes after copying the dictionaries folder to /tmp.

## Where Cameradar is the wrong tool

Cameradar is an active tool. It scans ports and it guesses credentials. Pointed at a production camera network during business hours, a dictionary attack can lock accounts, trip intrusion detection, or generate alerts that someone has to explain. The README's own security section is the acknowledgment that this is not a passive observer.

The second limitation is dictionary coverage. The README describes the route and credential stages as dictionary-based, which means the result is bounded by the wordlists you feed them. A camera with a non-default route and a strong password will come back as undiscovered, and that is a correct outcome for the tool, not a bug. Treating an empty credential result as proof that the camera is secure is a misreading of what the tool does.

The third is the discovery dependency described earlier. On a segmented network where scanning is blocked, the default mode returns nothing useful, and you have to move to --skip-scan and supply the inventory yourself. If you need continuous monitoring of a camera estate rather than a point-in-time assessment, this is not the architecture you want, because every run is an active scan.

## Cameradar and a general-purpose scanner like nmap

The honest comparison is with running nmap and a script yourself. Cameradar is built on nmap and masscan through Go wrappers, so the discovery layer is not novel. The difference is everything after discovery: the RTSP protocol handling through gortsplib, the route dictionary stage, the credential dictionary stage, and the aggregated report.

If you run nmap with the RTSP scripts you get open ports and whatever the NSE scripts return. You do not get a stream-route search, and you do not get a credential sweep unless you write one. Cameradar packages those three stages into one invocation and one report, which is the actual product. The trade-off is control: nmap exposes far more scanning technique, timing and evasion options than Cameradar surfaces, and Cameradar's --ports and --targets flags are the main levers you get. For a broad network survey, nmap is the better instrument. For a camera-specific assessment where you want routes and credentials in the same output, Cameradar saves you the glue code.

## Licence, maintenance and upgrade cost

Cameradar is MIT licensed, which is permissive and imposes no copyleft obligation on your own code. That is the whole of the licence story here; nothing in the repository suggests a dual licence or a commercial tier. This is not legal advice, and if you redistribute the binary inside a product you should read the LICENSE file yourself.

The repository is not archived and the last push was on 2026-09-21, two days before this writing. Releases are frequent: v6.2.1 on 2026-07-26, v6.2.0 on 2026-06-16, and v6.1.1 on 2026-03-09. The module path is versioned as /v6, so a major upgrade would be a new import path rather than a silent change.

Upgrade cost is mostly environmental. The Go toolchain floor moves with go.mod, currently 1.26.7, and the binary install path pins the module path and command directory. If you use the Docker image, the upgrade is a pull, but the image bundles nmap, masscan and libpcap from Alpine, so a base image change can affect scanning behaviour without any Cameradar release. Pinning an image tag rather than using latest is the cheap protection against that.

## Conclusion

Adopt Cameradar if you run authorized assessments of IP camera estates and want RTSP host discovery, model fingerprinting, and dictionary attacks in one binary with a Docker image and a plain UI option. Do not adopt it for passive monitoring or for any network you cannot put in writing as in scope, because its default behaviour is active port scanning plus credential guessing. Before your first run, verify three things: that the default port list (554, 5554, 8554, http, 322, 8322) matches the estate, that you have a route and credential dictionary you are allowed to use, and whether you need SSL_CERT_FILE for RTSPS targets with self-signed certificates.

## FAQ

### How do I check if someone is accessing my RTSP camera?

Cameradar is not a monitoring tool, so it will not tell you about an ongoing intrusion. It is an active assessment tool: it scans authorized targets for open RTSP hosts and runs dictionary attacks against routes and credentials, which tells you whether your camera is reachable and still using guessable defaults. Use it against your own network to find exposure, and use the camera's own logs to detect access.

### Can a hacker see me through my phone camera?

Cameradar targets RTSP video surveillance endpoints, not phone cameras, and the README describes no capability involving mobile device cameras. What it does cover is finding RTSP hosts on a target and attempting dictionary-based discovery of stream routes and credentials on cameras you are authorized to test.

### How do I tell if someone hacked into my RTSP camera?

Cameradar does not answer this, because it produces a point-in-time assessment rather than continuous monitoring. Running it against your own camera tells you whether the stream is reachable on the default ports and whether default credentials still work, which is the exposure side of the question rather than the intrusion side.

### Can websites get access to your camera?

The README does not discuss browser-based access to cameras and Cameradar has no web component. Its scope is RTSP endpoints reached over the network, with discovery on the default ports and dictionary attacks against stream routes and credentials.

## Sources

- [Issues](https://github.com/Ullaakut/cameradar/issues)
- [License: MIT](https://github.com/Ullaakut/cameradar/blob/master/LICENSE)
- [README](https://github.com/Ullaakut/cameradar/blob/master/README.md)
- [Releases](https://github.com/Ullaakut/cameradar/releases)
- [Ullaakut/cameradar on GitHub](https://github.com/Ullaakut/cameradar)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ullaakut-cameradar
