cameradar Documentation

Cameradar hacks its way into RTSP videosurveillance cameras

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy cameradar on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name cameradar --restart always ullaakut/cameradar:latest

1. Project Overview & Quickstart (Ullaakut/cameradar)

Cameradar

RTSP stream access tool

Cameradar scans RTSP endpoints on authorized targets, and uses dictionary attacks to bruteforce their credentials and routes.

What Cameradar does

  • Detects open RTSP hosts on accessible targets.
  • Detects the device model that streams the RTSP feed.
  • Attempts dictionary-based discovery of stream routes (for example, /live.sdp).
  • Attempts dictionary-based discovery of camera credentials.
  • Produces a report of findings.

Table of contents


Quick start with Docker

Install Docker and run:

bash
docker run --rm -t --net=host ullaakut/cameradar --targets <target>

Example:

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

This scans ports 554, 5554, and 8554 on the target subnet.
It attempts to enumerate RTSP streams.
For all options, see Configuration reference.

  • Targets can be CIDRs, IPs, IP ranges or a hostname.

    • Subnet: 172.16.100.0/24
    • IP: 172.16.100.10
    • Host: localhost
    • Range: 172.16.100.10-20
  • To use custom dictionaries, mount them and pass both flags:

    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

Install the binary

Use this option if Docker is not available or if you want a local build.

Dependencies

  • Go 1.25 or later

Steps

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

The cameradar binary is now in your $GOPATH/bin.
For available flags, see Configuration reference.

Install on Android (Termux)

These steps summarize a working Termux setup for Android.
Use Termux 117 from F-Droid or the official Termux site, not Google Play.

1) Set up Termux and Alpine

Install the required packages in Termux:

bash
pkg update
pkg install mc wget git nmap proot-distro

Install Alpine and log in:

bash
proot-distro install alpine
proot-distro login alpine

2) Install build tools in Alpine

bash
apk add wget git go gcc clang musl-dev make

3) Build Cameradar

Create a module path and clone the repo:

bash
mkdir -p go/pkg/mod/github.com/Ullaakut
cd go/pkg/mod/github.com/Ullaakut
git clone https://github.com/Ullaakut/cameradar.git
cd cameradar/cmd/cameradar
go install

4) Run Cameradar

Copy dictionaries and run the binary:

bash
mkdir -p /tmp
cp -r ../../dictionaries /tmp/dictionaries
/go/bin/cameradar --targets=<target> --custom-credentials=/tmp/dictionaries/credentials.json --custom-routes=/tmp/dictionaries/routes --ui=plain --debug

Replace <target> with an IP, range, host or subnet you are authorized to test.

Configuration

The default ports are 554, 5554, 8554, http, 322, and 8322.
If you do not specify ports, Cameradar uses those.

Example of scanning custom ports:

bash
docker run --rm -t --net=host \
    ullaakut/cameradar \
    --ports "18554,19000-19010" \
    --targets localhost

You can replace the default dictionaries with your own routes and credentials files.
The repository provides baseline dictionaries in the dictionaries folder.

bash
docker run --rm -t --net=host \
    -v /my/folder/with/dictionaries:/tmp/dictionaries \
    ullaakut/cameradar \
    --custom-routes /tmp/dictionaries/my_routes \
    --custom-credentials /tmp/dictionaries/my_credentials.json \
    --targets 172.19.124.0/24

RTSPS and TLS certificates

Use rtsps:// URLs to access RTSPS streams.

  • If the stream certificate is issued by a trusted public CA, no extra setup is needed.
  • If the stream certificate is self-signed or issued by a private CA, the OS trust
    store may reject it.
  • In that case, point SSL_CERT_FILE to the CA certificate (or server cert for a
    self-signed setup) when running Cameradar.

Example with local binary:

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

Example with Docker:

bash
docker run --rm -t --net=host \
        -e SSL_CERT_FILE=/tmp/certs/server.crt \
        -v /path/to/certs:/tmp/certs:ro \
        ullaakut/cameradar \
        --targets localhost \
        --ports 8322

If you prefer not to use SSL_CERT_FILE, add your CA certificate to the system trust
store used by your runtime environment.

Skip discovery with `--skip-scan`

If you already know the RTSP endpoints, you can skip discovery and treat each
target and port as a stream candidate. This mode does not run discovery and can be
useful on restricted networks or when you want to attack a known inventory.

Skipping discovery means:

  • Cameradar does not run discovery and does not detect device models.
  • Targets resolve to IP addresses. Hostnames resolve via DNS.
  • CIDR blocks and IPv4 ranges expand to every address in the range.
  • Large ranges create many targets, so use them carefully.

Example:

bash
docker run --rm -t --net=host \
    ullaakut/cameradar \
    --skip-scan \
    --ports "554,8554" \
    --targets 192.168.1.10

In this example, Cameradar attempts dictionary attacks against
ports 554 and 8554 of 192.168.1.10.

Choose the discovery scanner with `--scanner`

Cameradar supports two discovery backends:

  • nmap (default)
  • masscan

Use nmap when you want more reliable RTSP discovery: it performs service
identification and can better distinguish RTSP from other open ports.

Use masscan when scanning very large networks: it is generally faster and
more efficient at scale, but it does not provide service discovery.

bash
docker run --rm -t --net=host \
    ullaakut/cameradar \
    --scanner masscan \
    --ports "554,8554" \
    --targets 192.168.1.0/24

[!WARNING]
--scan-speed only applies to the nmap scanner.

Reduce false positives with `--framecheck`

Some cameras do not fully follow RTSP behavior and can return 200 OK even when
the route or credentials are wrong.

When you enable --framecheck, Cameradar validates each 200 OK by attempting
playback and waiting for an RTP packet.

Framecheck means:

  • Cameradar only accepts 200 OK when it can confirm frame generation.
  • If no RTP packet arrives, Cameradar treats the result as a false positive and continues attacking.
  • Route checks remain compatible with authentication challenges seen during probing.

--framecheck is disabled by default because it adds RTSP requests and can
significantly increase attack duration.

Example with Docker:

bash
docker run --rm -t --net=host \
        ullaakut/cameradar \
        --targets 192.168.1.0/24 \
        --ports "554,8554" \
        --framecheck

Example with local binary and environment variable:

bash
FRAMECHECK=true \
        cameradar \
        --targets 192.168.1.0/24 \
        --ports "554,8554"

Security and responsible use

Cameradar is a penetration testing tool.
Only scan networks and devices you own or have explicit permission to test.
Do not use this tool to access unauthorized systems or streams.
If you are unsure, stop and get written approval before scanning.

Output

Cameradar presents results in a readable terminal UI.
It logs findings to the console.
The report includes discovered hosts, identified device models, and valid routes or credentials.
If you specify a path for the --output flag, Cameradar also writes an M3U playlist with the discovered streams.

Check camera access

Use VLC Media Player to connect to a stream:

rtsp://username:password@address:port/route

For secure RTSP endpoints, use:

rtsps://username:password@address:port/route

Input file format

The file can contain IPs, hostnames, IP ranges, and subnets.
Separate entries with newlines.
Example:

text
0.0.0.0
localhost
192.17.0.0/16
192.168.1.140-255
192.168.2-3.0-255

When you use --skip-scan, Cameradar expands each entry into explicit IP
addresses before building the target list.

Command-line options and environment variables

The complete CLI and environment variable reference is maintained in Configuration reference.

This includes all supported flags, defaults, accepted values, and env var mapping.

Build and contribute

Docker build

Run the following command in the repository root:

docker build . -t cameradar

The resulting image is named cameradar.

Go build

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

The cameradar binary is now in $GOPATH/bin/cameradar.

Frequently asked questions

See Troubleshooting & FAQ

Examples

Running cameradar on your own machine to scan for default ports

docker run --rm -t --net=host ullaakut/cameradar --targets localhost

Running cameradar with an input file, logs enabled on port 8554

docker run --rm -t --net=host -v /tmp:/tmp ullaakut/cameradar --targets /tmp/test.txt --ports 8554

Running cameradar on a subnetwork with custom dictionaries, on ports 554, 5554, 8554, 322, and 8322

docker run --rm -t --net=host -v /tmp:/tmp ullaakut/cameradar --targets 192.168.0.0/24 --custom-credentials "/tmp/dictionaries/credentials.json" --custom-routes "/tmp/dictionaries/routes" --ports 554,5554,8554

Running cameradar with masscan discovery

docker run --rm -t --net=host ullaakut/cameradar --scanner masscan --targets 192.168.0.0/24 --ports 554,8554

License

Copyright 2026 Ullaakut

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2. Official Technical Reference & Guides (Ullaakut/Ullaakut.github.io)

Get started building your personal website

Showcase your software development skills

This repository gives you the code you'll need to kickstart a personal website that showcases your work as a software developer. And when you manage the code in a GitHub repository, it will automatically render a webpage with the owner's profile information, including a photo, bio, and repositories.

Your personal website is waiting to be personalized, though. It includes space to highlight your specific areas of interest in software development, like languages or industries. And it's standing by to publish your next great blog post.

It's all possible using the combination of Jekyll (for building your website), GitHub Pages (for hosting your website), and GitHub's API (for automatically populating your website with content).

Installation

Fork the `github/personal-website` repo

You'll be making your own copy of the "personal website starter" repository so you have your own project to customize. A "fork" is a copy of a repository. So select "Fork" atop the github/personal-website repository.

Once you've found a home for your forked repository, it's yours. You're the owner, so you're ready to publish, if you wish.

Install in your local development environment

If you want to manage your website in a local web development environment, you'll be using Ruby.

Once you've found a home for your forked repository, clone it.

Install Jekyll

Jekyll is a Ruby Gem that can be installed on most systems.

  1. Install a full Ruby development environment
  2. Install Jekyll and bundler gems
text
gem install jekyll bundler
  1. Change into your new directory
text
cd personal-website
  1. Install missing gems
text
bundle install
  1. Build the site and make it available on a local server
text
bundle exec jekyll serve

You should see something like:

text
Configuration file: /octocat/personal-website/_config.yml
            Source: /octocat/personal-website
       Destination: /octocat/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
   GitHub Metadata: No GitHub API authentication could be found. Some fields may be missing or have incorrect data.
                    done in 14.729 seconds.
 Auto-regeneration: enabled for '/octocat/personal-website'
    Server address: http://127.0.0.1:4000
  Server running... press ctrl-c to stop.

Don't worry about the "No GitHub API authentication could be found" message. API authentication is only necessary if you intend to display more detailed metadata, like a branch name.

  1. Now browse to http://localhost:4000

Publish

When you host your personal website's code on GitHub, you get the support of free hosting through GitHub Pages.

The fastest approach is to rename your repository username.github.io, where username is your GitHub username (or organization name). Then, the next time you push any changes to your repository's master branch, they'll be accessible on the web at your username.github.io address.

If you want to use a custom domain, you'll want to add it to your repository's "Custom domain" settings on github.com. And then register and/or configure your domain with a DNS provider.

Customization

It's your website, and you control the source code. So you can customize everything, if you like. But we've provided a handful of quick customizations for you to consider as you get your website off the ground.

Quick configuration changes

Most customizations can be done in a matter of seconds, by revising your repository's _config.yml file. Just remember to restart your local server each time you save new changes so your Jekyll-powered website rebuilds correctly:

  1. Shut down your server by entering the keyboard command CTRL+c
  2. Restart your server: bundle exec jekyll serve

Layout

Your website will display in a two-column layout by default on larger-screen devices, with your photo, name, and basic information displayed in a left-aligned "sidebar." You can quickly switch to a "stacked" single-column layout by changing the line in your _config.yml file that reads layout: sidebar to layout: stacked.

Style

Your website appears with a "light" white and gray background by default, with dark text. You can quickly switch to a "dark" background with white text by changing the line in your _config.yml file that reads style: light to style: dark.

Projects

The "My Projects" section of your website is generated by default with your nine most recently "pushed" repositories. It also excludes repositories that you forked, by default. But each of these parameters can be quickly customized in your repository's _config.yml file, under the projects dictionary line.

Parameters include:

  • sort_by: The method by which repositories are sorted. Options include pushed and stars.
  • limit: The maximum number of repositories that will be displayed in the "My Projects" section of your website. Out of the box, this number is set to 9.
  • exclude:
    • forks: When true, repositories you've forked will be excluded from the listing.
    • projects: A list the repository names you want to exclude from the listing.

Topics

Your website comes pre-configured with three topics (e.g. "Web design" and "Sass") that appear in a section titled "My Interests." These are also stored in your repository's _config.yml file, where you can define each topic's name and two other optional details:

  • web_url: The web address you'd like to your topic to link to (e.g. https://github.com/topics/sass).
  • image_url: The web address of an (ideally square) image that you'd like to appear with your topic.

Social media

Your website supports linking and sharing to social media services you're using, including Behance, Dribbble, Facebook, LinkedIn, Medium, Stack Overflow, Twitter, and YouTube. To identify the services you use:

  1. Edit your repository's _config.yml file.
  2. Edit the social_media dictionary line, and represent the services you like in a simple key: value form:
text
social_media:
  behance: your_username
  dribbble: your_username  
  facebook: your_username
  hackerrank: your_username
  instagram: your_username
  keybase: your_username
  linkedin: your_username
  medium: your_username
  stackoverflow: your_user_id
  telegram: your_username
  twitter: your_username
  unsplash: your_username
  vk: your_username
  website: http://your_website_url
  youtube: your_username

Links to your profile for each of the services you define will appear in the <header> of your website, appended to your bio. And if those services support sharing, any blog posts that you publish will include links to share that post using each social media service.

Note: This feature is supported by two files in your repository:

  • /_data/social_media.yml: Defines each of the supported services, including variable name, display name, URL path, and SVG icon.
  • /_includes/social_media_share_url.html: Outputs the share URL required for any of the supported social media services that support sharing URLs.

If you're interested in adding a social media service that's not already supported in this repo, you can edit these two files to build that support.

Adding pages

To add a page to your website (e.g. detailed resume):

  1. Create a new .html or .md file at the root of your repository.
  2. Give it a filename that you want to be used in the page's URL (e.g. http://yoursite.dev/filename).
  3. At the start of your file, include the following front matter:
text
---
layout: default
---

Adding blog posts

To add a blog post to your website:

  1. Create a new .md file in your repository's /_posts/ directory.
  2. Give it a filename using the following format:
text
YEAR-MONTH-DAY-title.MARKUP
  1. At the start of your file, include the following front matter:
text
---
title: "The title of my blog post"
---

Your website comes with a placeholder blog post that you can reference. Notably, its front matter declares published as false, so that it won't appear on your website.

While you can define a layout in the front matter, your website is pre-configured to assign the post layout to all of the posts in your /_posts/ directory. So you don't have to declare that in your posts.

Jekyll's conventions for authoring and managing blog posts is very flexible. You can learn more in Jekyll's documentation for "Posts."

Content and templates

To give you a sound foundation to start your personal website, your repository includes a handful of "includes" -- dynamic .html files that are re-used throughout your website. They're all stored in the /_includes/ directory.

There are the usual suspects, like header.html and footer.html. But there are few more worth pointing out:

  • interests.html: A heading and dynamic list of "My Interests," which is populated with the topics you list in your _config.yml.
  • masthead.html: A collection of your avatar, name, bio, and other metadata that's displayed prominently on all your webpages to help identify what the website is about.
  • post-card.html: A compact, summarized presentation of a blog post, re-used to display a listing of your latest blog posts.
  • projects.html: A heading and dynamic list of "My Projects," which is populated with a listing of your newest GitHub repositories.
  • repo-card.html: A compact, summarized presentation of a repository, re-used to display a listing of your GitHub repositories.
  • thoughts.html: A heading and dynamic list of "My Thoughts," which is populated with a listing of your latest blog posts.
  • topic-card.html: A compact, summarized presentation of a topic (defined in your _config.yml), re-used to display a listing of your interests.

Layouts

Your repository comes with three layouts:

  • default: Not used by any of the built-in pages or posts, but useful for any new pages you create.
  • home: Used by your index.html homepage to display listings of your projects, interests, and (optionally) your blog posts.
  • post: Used by default by the posts in your /_posts/ directory.

Jekyll's convention for defining layouts is very flexible. You can learn more about customizing your layouts in the Jekyll "Layouts" docs.

Styles

Your website is pre-configured to use GitHub's very flexible CSS framework called "Primer,". It's currently referenced within your styles.scss file, using the CSS import at-rule:

text
@import url('https://unpkg.com/primer/build/build.css');

You are, of course, welcome to remove it or replace it with another framework. Just bear in mind that the HTML that your website came pre-packaged with references multiple Primer "utility classes" to define things like column widths, margins, and background colors.

You also have the option to add on to and extend Primer's styles by adding custom CSS to your /assets/styles.scss Sass stylesheet. By editing this file, you can customize your website's color scheme, typography, and more.

License

The theme is available as open source under the terms of the MIT License.