Skip to content

Orange-Cyberdefense/cam-amber

Repository files navigation

cam-amber

A toolkit for camera discovery and assessment during penetration tests using ONVIF and RTSP.

Cam-Amber logo

Contents:

CamAmber

Manipulate intercepted RTSP stream to duplicate it and/or replace it. The tool automates a few things, but you still have some work to do (the other scripts in the toolkit can help), see instructions below.

Here we consider that the stream was already running before our attack and that we do not have initialization information (no RTSP session establishment).

WARNING: This program could INTERRUPT the network stream. PLEASE DO NOT USE ON SENSITIVE ENVIRONMENTS.

Requirements

The program is in C and requires gcc for compiling.

If you use the auto-MITM feature, arpspoof is required (apt install dsniff).

So far only Debian OS are supported. We rely on sysctl and iptables to change network settings at system level.

TL;DR

  1. Retrieve the destination port of the stream
  2. (Optional) Set up a MITM attack manually, or use -M option
  3. Run CamAmber with either "redirect" or "replace" mode (replace also redirects)
  4. View the stream locally (requires additional, SDP-related steps)

Step 1 : Retrieve the destination port of the stream

This parameter is required for CamAmber to work. It will not find it itself (too many chances of false positive). You can retrieve it if you have access to the traffic of the source/destination or by running a first man-in-the-middle attack:

  • sudo ettercap -T -M arp:remote /<camera_ipaddr>// /<viewer_ipaddr>//
  • Quit when you have the destination port

Step 2 : Set up the MITM attack (or let CamAmber do it)

CamAmber requires to be in a man-in-the-middle position between the camera and a legitimate viewer (or anything else). Use option -M to let CamAmber do it (uses arpspoof).

Note: if you want to run you own MITM attack, you need to use a technique that let the system handle IP forwarding (see detailed instructions)

Step 3: Run CamAmber

Compile it with make.

Usage: ./camamber -m [mode] -i [iface] [network_info]

arguments:
 -m mode    Specify what CamAmber must do (redirect or replace)
 -i iface   Network interface to use.

 -M         Enable auto Man-in-the-middle attack (relies on arpspoof).

 -s src     IPv4 address of the stream (usually a camera)
 -d dest    IPv4 address of the original destination (e.g. a VMS or NVR)
 -p port    Destination port of the network stream
 -r redir   IPv4 address to send the duplicated stream to (e.g. 127.0.0.1)
 -f frames  Number of frames to record and loop (replace mode only)

 -v         Print additional information to terminal.

CamAmber must be run as sudo. It requires root privileges to play with iptables, nfqueues and sockets.

Mode: redirect

sudo ./camamber -m redirect -i <iface> -s <camera_ipaddr> -d <viewer_ipaddr> -p
<stream_dest_port>

When activated, the original stream will not be interrupted (hopefully), however the stream will be duplicated and sent to another IP. Default behavior is to send it to localhost to be able to open and view the network stream on your host (e.g. with VLC), but you can also send it somewhere else (why?).

Additional steps are required to be able to view the stream locally (you need information about the stream). Details are given below.

Mode: replace

sudo ./camamber -m replace -i <iface> -s <camera_ipaddr> -d <viewer_ipaddr> -p
<stream_dest_port>

Replace mode will first record a short video sequence from the stream during a few seconds then send this sequence over and over again to the original viewer instead of the real stream. Stopping CamAmber will restore the stream without interrupting it (hopefully) but the "fake" stream may remain for a few seconds or minutes.

You don't need to view the stream locally for the attack to work. However, if you want to, redirect mode works as well in replace mode.

Additional steps are required to be able to view the stream locally (you need information about the stream). Details are given below.

Step 4: View the stream

For your media player (here, VLC) to be able to read the RTSP stream, you need to feed it with the video format. The format is be described in a SDP (Session Description Protocol, RFC 8866) file, usually sent during session initialization (which we may not have).

There are a few ways to retrieve a valid SDP file, or to create one:

  • Catch a RTSP session init and extract the SDP packet then store it in a file (can be done for instance with Wireshark, see detailed instructions).

  • Init a RTSP session yourself and extract the SDP packet. If the RTSP session requires authentication, you need valid credentials. Can be done with CamAmber-SDP.

  • Guess or bruteforce the correct parameters and generate a SDP yourself (low chances of success). CamAmber-SDP can be used to gather some of these details and to build a SDP file.

Please note that there are limitations and that crafted SDP files may not work for complex video formats such as H.264 and H.265.

Once you have your valid SDP file, open it with a media player:

vlc my_rtp.sdp

The correct local destination port of the stream must be supplied to make it work (line to change: m=video <port> RTP/AVP XX).

CamAmber-Discover

Utility to discover video-related components on a network using the protocols SSDP and WS-Discovery, in multicast and/or unicast.

Requirements

This is a Python 3.12+ script relying only on built-in libraries.

Modes

Usage

camamber-discover.py [-h] [-v] [-m protocol] [-t ip or range]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print additional information
  -m protocol, --mode protocol
                        Only test with one protocol (default: test all)
  -t ip or range, --target ip or range
                        Target IPv4 address or range to test via unicast.

Without argument, the script will run only multicast discovery using both protocols (SSDP and WS-Discovery). If the target option is set (-t), a unicast discovery will be performed on all IP adresses specified, for both protocols by default.

SSDP and WS-Discovery are originally multicast protocols. We have added unicast support because of the limitations of multicast discovery (multicast requests are usually not transmitted outside of the VLAN you are in so you can only see devices on the same VLAN). Some devices supporting SSDP or WS-Discovery via multicast may not respond to SSDP or WS-Discovery via unicast.

  • -m (modes) can be used to choose the type of discovery : unicast, multicast, ssdp, wsdiscovery. Default is all types of discovery. Unicast discovery is done only if -t is set.
  • -t (target) takes a single IPv4 address, a IPv4 range or a file containing a list of IP addresses.

CamAmber-SDP

Utility to retrieve, craft or manipulate SDP files.

Requirements

This is a Python 3.12+ script relying only on built-in libraries.

Usage

camamber-sdp.py [mode] [additional parameters]

Modes

CamAmber-SDP currently supports three modes to get SDP or info to create one.

  1. Get: Establish a RTSP session to retrieve the SDP
  2. Listen: Listen to the incoming stream to gather a few info from RTP frames
  3. Forge: Create a SDP file from scratch with user-supplied data

When running with CamAmber, the SDP file needs to be updated with the actual destination port in the m=video line. You can edit it directly or do it with:

python camamber-sdp.py -i my_default_sdp.sdp -p <port>

Mode: get

Establish a legitimate RTSP session with the device to retrieve a valid SDP file.

usage: camamber-sdp.py [-h] [-v] [-o filename] [-s stream_uri] [-u username] [-p password]
                       [-d port]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print additional information
  -o filename, --output filename
                        Filename to write the SDP file to
  -s stream_uri, --stream stream_uri
                        RTSP stream URI
  -u username, --user username
                        Username for RTSP connection (if any)
  -p password, --passwd password
                        Password for RTSP connection (if any)
  -d port, --dport port
                        Stream destination port to set in the SDP

The only mandatory argument is -s stream_uri with format rtsp://.... You can find it by:

  • Requesting the ONVIF webservice (see CamAmber-ONVIF)
  • Find it in the device documentation
  • Bruteforce it (ex: Cameradar)

Credentials are required if the RTSP stream establishment requires authentication.

Mode: listen

This will not create any SDP file, however you can run it while the man-in-the-middle attack is running to extract useful data from the RTP frames to be able to build a SDP afterwards (Payload type and codec, RFC 6184).

usage: camamber-sdp.py [-h] [-v] [-o filename] [-d ip_addr] [-p port]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print additional information
  -o filename, --output filename
                        Filename to write the SDP file to
  -d ip_addr, --dest ip_addr
                        IP address on which RTP frames arrive
  -p port, --port port  Local port to listen to

Mode: forge

Create a SDP file from scratch with info supplied in command line. As there are many possibilities, only "common" formats are proposed (e.g. we assume that a profile ID always use the same level ID, which is not certain).

If -i is provided, the SDP file will not be created from scratch but input will be updated with user-supplied information (useful to update the port).

H.264 and H.265 require detailed video format info that cannot be created from scratch (RFC 6184 for H.264, RFC 7798 for H.265). So we build a SDP file that lack them. Media players may be able to read the stream without it (not always, unfortunately).

usage: camamber-sdp.py [-h] [-v] [-o filename] [-i sdp_file] [-d ip_addr] [-p port]
                       [-c codec] [-rp profile] [-pt pt] [-cr clockrate]
                       [-pm packetization mode] [-pi profileid]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print additional information
  -o filename, --output filename
                        Filename to write the SDP file to
  -i sdp_file, --input sdp_file
                        Existing SDP to adapt (if any)
  -d ip_addr, --dest ip_addr
                        IP address on which the video stream arrives
  -p port, --port port  Port on which the video stream arrives
  -c codec, --codec codec
                        Stream format
  -rp profile, --rprofile profile
                        RTP profile (most common: RTP/AVP)
  -pt pt, --payloadtype pt
                        Payload type (most common: 96)
  -cr clockrate, --clockrate clockrate
                        Clock rate (most common: 90000)
  -pm packetization mode, --packetmode packetization mode
                        Packetization mode (most common: 1)
  -pi profileid, --profileid profileid
                        Profile ID (Baseline, Main, High)

Once you have your SDP file ready, you can use it while CamAmber is running to read an intercepted RTSP video stream :) (vlc camamber.sdp)

CamAmber-ONVIF

Dependencies

This is a Python 3.12+ requiring package onvif-zeep for all modes.

python -m venv camamber
source camamber/bin/activate
pip install onvif-zeep
python camamber-onvif.py

VLC is required for screen mode.

Usage

camamber-onvif.py [mode] [additional parameters]

Three modes are available so far: test, rtsp, discover and screen. For all modes:

  • target is either an IPv4 address, an IPv4 range (A.B.C.D/X) or a file containing a list of IPv4 addresses (one per line).
  • username and password are optional but must be supplied if the remote ONVIF service has authentication enabled.

test

Check if the ONVIF service is running on a port and if it requires authentication. Standard ports 80, 8080, 8000 and 8899 are tested, you can add more by editing the code.

camamber-onvif.py test target

discover

Retrieve useful data from a device using ONVIF.

camamber-onvif.py discover target port [username] [password]

rtsp

Only retrieves the RTSP stream URL from the device using ONVIF.

camamber-onvif.py rtsp target port [username] [password]

screen

Take a screenshot of the video stream (requires VLC to be installed).

camamber-onvif.py screen target port [username] [password]

Note : You may not need this feature as the discover function gives a link to access a snapshot from the camera (but this is not always supported).

FAQ

How to set up my own man-in-the-middle attack?

If you want to run your own man-in-the-middle attack and not rely on CamAmber's -M option:

You need to use a tool/option that does not perform its own packet forwarding, because it must be handled by your system like this:

  • Enable IP forwarding (sudo sysctl -w net.ipv4.ip_forward=1)
  • Change iptable rule for packet forward from DROP to ACCEPT (sudo iptables -P FORWARD ACCEPT)

Example with ettercap and arpspoof:

sudo arpspoof -i <iface> -t <viewer_ipaddr> <camera_ipaddr> -r
sudo ettercap -T -M arp:remote /<camera_ipaddr>// /<viewer_ipaddr>// -o

-o is required for ettercap here, because it prevents it from doing its own forwarding.

Before running CamAmber, check that the MITM works with:

sudo tcpdump -ni <iface> host <viewer_ipaddr> and udp -vvv

How do I extract a SDP file from RTSP ini frames?

If you are lucky enough to capture the RTSP session initialization frames, it is really easy to extract the SDP file and to save it for later use.

This method was discovered in the book Practical IoT Hacking, The Definitive Guide to Attacking the Internet of Things by Fotios Chantzis and Ioannis Stais. I encourage you to read this book, which contains many interesting tricks for IoT hacking :)

If you have captured the RTSP init in Wireshark, there should be a packet tagged "RTSP/SDP". Right-click on it > Export Packet Bytes and save the file as XX.sdp.

The SDP file should look like this (parameters may change):

v=0
o=- 0 0 IN IP4 127.0.0.1
s=CamAmber
c=IN IP4 127.0.0.1
t=0 0
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=recvonly
a=fmtp:96 packetization-mode=1;profile-level-id=640029;sprop-parameter-sets=Z2QAKawbGoBQBb/wFuAgICgAAB9AAAdTB0MAAX14AAB3NZXeXGhgAC+vAAAO5rK7y4U=,aO44MA==

Note on AI use

The author of this toolkit is not a big fan of AI but it has still been used for the things listed below. All the information provided have been checked in RFCs and all the code samples have been rewritten:

  • Code line required to access the RTSP Stream URI information in a response to an ONVIF Web Server Get request using the library onvif-zeep (camamber-onvif.py:onvif_getstreaminfo)
  • Help to understand RFC 8866 and RFC 6184 for SDP format, especially the a=fmtp line (camamber-sdp.py)
  • Help to understand netfilter queues and associated iptables rules (camamber.c)
  • RTP frames parsing and checksum calculation in C (camamber.c)

Where can I find more information?

RFC:

Research material:

Tooling:

Handbooks and tutorials:

About

A toolkit for camera discovery and assessment during penetration tests.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors