
CVE-2025-31200 - @Noahhw46 l'ha capito
Proof-of-concept per la patch di CoreAudio (CVE-2025-31200) in iOS 18.4.1. Write-up qui https://blog.noahhw.dev/posts/cve-2025-31200/.
Sono riuscito a portare questo a una scrittura controllata, se non arbitraria. Il write-up arriverà presto. Tuttavia, per vederla di persona, dovrai compilare su una versione di macOS precedente alla patch: < 15.4.1. Puoi riprodurre l'audio con l'hook lldb check-mismatch (usando un semplice harness che riproduce solo l'audio) per osservare la scrittura. Non è ancora una grande scrittura arbitraria, come ho accennato sopra per alcune ragioni - ma principalmente perché non sono ancora sicuro al 100% in quale fase della pipeline di decodifica si trovino questi valori del frame buffer quando vengono rimappati. Mi fermo qui però per lavorare al write-up, se qualcuno vuole riprendere la cosa.
Io @noahhw46 (non ci sarei riuscito senza questo setup @zhouwei) l'ho capito (write-up in arrivo). Tuttavia, c'è ancora molto da capire. Ho aggiunto qui la prima parte dei prossimi passi della mia indagine per mostrare esattamente cosa fa il bug davvero. check-mismatch è un altro script lldb che può essere usato con un poc funzionante per mostrare esattamente il mismatch creato tra mRemappingArray e la mappa di permutazione in APACChannelRemapper::Process (nello specifico in APACHOADecoder::DecodeAPACFrame).
The mRemappingArray is sized based on the lower two bytes of mChannelLayoutTag.
By creating a mismatch between them, a later stage of processing in APACHOADecoder::DecodeAPACFrame is corrupted.
When the APACHOADecoder goes to process the APAC frame (permute it according to the channel remapping array), it uses the mRemappingArray as the permutation map to do the well, channel remapping. It seems like the frame data that is being remapped is sized based on mTotalComponenets.
Quando riproduci il file audio output.mp4 (ad esempio con AVAudioPlayer), APACChannelRemapper::Process leggerà e poi scriverà fuori dai limiti.
Puoi vedere la prima lettura fuori dai limiti se abiliti Guard Malloc in Xcode:
Senza Guard Malloc, APACHOADecoder::DecodeAPACFrame andrà successivamente in crash con una memmove non valida:
Il README precedente di @zhuowei è di seguito:
Sto cercando di capire la patch di CoreAudio (CVE-2025-31200) in iOS 18.4.1.
Non l'ho ancora capito.
Attualmente, ottengo messaggi di errore diversi quando decodifico output.mp4 su macOS 15.4.1:
error 01:10:26.743480-0400 getaudiolength <private>:548 Invalid mRemappingArray bitstream in hoa::CodecConfig::Deserialize()
error 01:10:26.743499-0400 getaudiolength <private>:860 Error in deserializing ASC components
rispetto al simulatore Xcode per visionOS 2.2:
error 01:09:21.841805-0400 VisionOSEvaluation APACProfile.cpp:424 ERROR: Wrong profile index in GlobalConfig
error 01:09:21.841914-0400 VisionOSEvaluation APACGlobalConfig.cpp:894 Profile and level data could not be validated
quindi sto incappando nel nuovo controllo, ma non so come fargli sovrascrivere davvero qualcosa.
La funzione modificata sembra essere apac::hoa::CodecConfig::Deserialize in /System/Library/Frameworks/AudioToolbox.framework/AudioCodecs.
APAC è Apple Positional Audio Codec
HOA è Higher-order Ambisonics.
Se guardi un file di esempio dal tracker dei problemi di ffmpeg:
$ avmediainfo ~/Downloads/clap.MOV
Asset: /Users/zhuowei/Downloads/clap.MOV
<...>
Track 3: Sound 'soun'
Enabled: No
Format Description 1:
Format: APAC 'apac'
Channel Layout: High-Order Ambisonics, ACN/SN3D
Sample rate: 48000.0
Bytes per packet: 0
Frames per packet: 1024
Bytes per frame: 0
Channels per frame: 4
Bits per channel: 0
System support for decoding this track: Yes
Data size: 43577 bytes
Media time scale: 48000
Duration: 0.898 seconds
Estimated data rate: 363.142 kbit/s
Extended language tag: und
1 segment present
Index Media Start Media Duration Track Start Track Duration
1 00:00:00.000 00:00:00.898 00:00:00.000 00:00:00.898
Member of alternate group 0: (2, 3)
Puoi convertire in APAC con afconvert -o sound440.m4a -d apac -f mp4f sound440hz.wav.
Usando bindiff su iOS 18.4.1 rispetto a 18.4, sembra che la lettura di mRemappingArray ora controlli il AudioChannelLayout* globale all'offset 0x58 per il numero di canali, invece del AudioChannelLayout* di rimappatura all'offset 0x78.
Il file encodeme.mm codifica APAC, e uno script LLDB forza elementi extra in mRemappingArray e nel AudioChannelLayout di rimappatura:
./build_encodeme.sh
./run_encodeme.sh