DVRIP/Sofia Protocol Dissector for Wireshark (Written in Lua)

DVRIP/Sofia Protocol Dissector for Wireshark (Written in Lua)

posted Originally published at dev.to 5 min read

A Wireshark dissector for DVRIP/Sofia protocol found on Xiongmai based IP cameras.

Full working dissector code is available at a DVRIP analysis repository.

Full writeup of a sample IP camera on which this dissector was tested is available at Besder 6024PB-XMA501 IP camera security investigation repository.

Table of Contents

Usage

Linux

cp dvripWireshark.lua /usr/lib/wireshark/plugins/

Windows

Copy dvripWireshark.lua to %APPDATA%\Wireshark\plugins

DVRIP/Sofia Ports

This dissector is based on a DVRIP Wireshark Dissector for Port TCP/37777 (Dahua IP camera), which can be found here: https://github.com/r4bit999/dvrip-analysis/tree/master

DVRIP/Sofia protocol found in Xiongmai-based IP cameras run on the following ports:

  1. TCP/34567 for local controls and media stream.
  2. TCP/6611 for cloud controls and media stream.
  3. UDP/34569 and UDP/34571 for local configs.
  4. UDP/7999 and UDP/8765 for cloud configs.

Test Device

Tested on Besder 6024PB-XMA501 IP camera:

Model: XM530_50X50-WG_8M
Firmware version: V5.00.R02.00030747.10010.349f17

DVRIP/Sofia Headers

Aside from the main DVRIP/Sofia message header, protocol's media payloads have their own headers. All media payload header fields (except first 4 bits - signature that indicates the type of a media payload) are reordered to their little-endian (LE) values.

Media payload headers were reconstructed based on Xiongmai bitstream frame format document.

DVRIP/Sofia Message Header

Header description of a single DVRIP/Sofia message is based on Digital Video Recorder Interface Protocol document, the actual diagram being on page 7.

Image description

  1. BIT 0: message header bit, fixed as 0xFF.
  2. BIT 1: observed to be equal to 0 for requests and equal to 1 for responses from the IP camera.
  3. BIT 2: reserved bit 1:
    • Equals 0 when H.264 video codec is used (BIT4 = 0x02 on I-Frame header).
    • Equals 1 when H.265 video codec is used (BIT4 = 0x12 on I-Frame header).
  4. BIT 3: reserved bit 2:
    • Equals 128 when DVRIP message contains audio frames.
    • Equals 0 otherwise.
  5. BIT 4-7: session ID. Assigned by the camera after successful login. Needs to be present in every subsequent message.
  6. BIT 8-11: sequence number. Increments from 0 after startup, and after reaching the (unknown) maximum, starts from 0 again.
  7. BIT 12: total number of messages in a single packet. Value of 0 or 1 indicate a single message per packet.
  8. BIT 13: number of a current message in a packet. Meaningful only when the value of total packets (BIT 12) is greater than 1.
  9. BIT 14-15: command code (also called message id). The code defines what action to perform.
  10. BIT 16-19: data (payload) length. Length of a JSON payload, which starts immediately after DVRIP/Sofia header.

Image description

Audio Header

Image description

  1. BIT 0-3: signature
  2. BIT 4: audio codec (0x0e = G711A)
  3. BIT 5: sampling rate (0x02 = 8kHz sampling)
  4. BIT 6-7: length of audio payload

Image description

I-Frame Header

Image description

  1. BIT 0-3: signature
  2. BIT 4: video codec (0x01 = MPEG4, 0x02 = H.264, 0x12 = H.265)
  3. BIT 5: encoded framerate (variable; 1-25 for PAL, 1-30 for NTSC)
  4. BIT 6: low 8 bits of image width; the value is actual width divided by 8
  5. BIT 7: low 8 bits of image height; the value is actual height divided by 8
  6. BIT 8-11: datetime of the capture
  7. BIT 12-15: length of I-Frame payload

Image description

First 4 bits of an I-Frame payload (BITS 16-19) are equal to 0x00000001

Same exact header fields are shared between I-Frames (FC) and snapshots (FE).

P-Frame Header

Image description

Extension of I-Frames.

  1. BIT 0-3: signature
  2. BIT 4-7: length of P-Frame payload

Image description

First 4 bits of a P-Frame payload (BITS 8-11) are equal to 0x00000001

Information Frame Header

Image description

  1. BIT 0-3: signature
  2. BIT 4: general information (unconfirmed)
  3. BIT 5: unused value
  4. BIT 6-7: payload length

Image description

Used for information transmission. First bit after signature (bit 4):

  1. 0x01 - general information.
  2. 0x06 - unknown value.

Saving Streams

This dissector is programmed to reconstruct audio and video streams from the packet capture (.pcap) file. In Wireshark GUI, navigate to the Tools menu and select DVRIP Save Streams entry. In the pop-up dialog box, enter the desired folder to save streams in.

File names of saved streams are structured as follows:

<camera-ip-address>_<reserved-bit-1>_<reserved-bit-2>_<audio|video>.<g711|h265>

Cloud Communications

Same logic is used both for local and cloud communications with the IP camera. Only observed difference is that for local communications, port TCP/34567 is used and for cloud communications, it is port TCP/6611.

DVRIP/Sofia Protocol Field List

DVRIP/Sofia protocol fields used in this protocol dissector:

Field NameFilter NameDescription
DVRIP_headerdvrip.headerFull DVRIP/Sofia header
DVRIP_header_iddvrip.header_idFirst byte of DVRIP header, observed to be 0xFF
DVRIP_req_respdvrip.req_respRequest/response byte. 0x00 for request and 0x01 for response
DVRIP_reserved_1dvrip.reserved_1Reserved bit 1. Indicates video stream
DVRIP_reserved_2dvrip.reserved_2Reserved bit 2. Indicates audio stream
DVRIP_session_iddvrip.session_idID of an established session
DVRIP_sequence_iddvrip.sequence_idSequence ID. Message number in the current session
DVRIP_total_packetsdvrip.total_packetsNumber of messages in a single packet. 0 or 1 indicate a single message
DVRIP_current_packetdvrip.current_packetcurrent message in a packet. Meaningful only when total packets > 1
DVRIP_command_codedvrip.command_codeCommand code/Message ID. Identifies an action to perform
DVRIP_payload_sizedvrip.payload_sizePayload size of a current message
DVRIP_payload_JSON_RAWdvrip.dataJSON data payload. Starts immediately after header
DVRIP_newlinedvrip.newlineTrailin newline after JSON payload
DVRIP_cloud_ipdvrip.cloud_ipIP address of cloud relay
DVRIP_home_ipdvrip.home_ipPublic IP address of a home network
DVRIP_device_iddvrip.device_idSerial number of IP camera
DVRIP_device_macdvrip.device_mac_addressMAC address of IP camera
DVRIP_encrypteddvrip.encryptedEncrypted payload of a message
DVRIP_signaturedvrip.signatureSignature of media frame
DVRIP_stream_typedvrip.stream_typeVideo stream type
DVRIP_frameratedvrip.framerateStream framerate
DVRIP_widthdvrip.widthWidth of video frame (divided by 8)
DVRIP_heightdvrip.heightHeight of video frame (divided by 8)
DVRIP_datetimedvrip.datetimeStart date of the stream
DVRIP_media_payload_sizedvrip.media_payload_sizePayload size of media frame
DVRIP_sampling_ratedvrip.sampling_rateAudio sampling rate
DVRIP_unused_fielddvrip.unused_fieldUnused field in information frame header

More Posts

Emotet + Cobalt Strike — Dissecting a Multi-Stage Attack in Wireshark

himanshu.modi2021 - Apr 7

Optimizing the Clinical Interface: Data Management for Efficient Medical Outcomes

Huifer - Jan 26

Defending Against AI Worms: Securing Multi-Agent Systems from Self-Replicating Prompts

alessandro_pignati - Apr 2

The Audit Trail of Things: Using Hashgraph as a Digital Caliper for Provenance

Ken W. Algerverified - Apr 28

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

9 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!