Resumo `SctpSackChunk.ParseChunk` lê os campos `numGapAckBlocks` e `numDuplicateTSNs` (cada um até 65535 ) diretamente de um bloco e loops SCTP SACK controlados pelo atacante que muitas vezes leem 4 bytes por iteração, sem validação das contagens em relação ao comprimento do pedaço ou ao buffer de recebimento. Um único pedaço SACK criado de uma força negociada de pares do WebRTC lê depois do fim do 262144 -byte receba buffer, levantando `IndexOfRangeException`, que não é pego pelo manipulador recuperable e termina o thread dedicado do SCTP receber — matando permanentemente a associação SCTP e todos os canais de dados. ## Causa Raiz `src/SIPSorcery/net/SCTP/Chunks/SctpSackChunk.cs`: - `ushort numGapAckBlocks = NetConvert.ParseUInt 16 (buffer, startPosn + 8 );` (: 141 ) - `uprhort numDuplicateTSNs = NetConvert.ParseUInt 16 (buffer, startPosn + 10 );` (: 142 ) - loop de gap- ack (: 146 ) e duplicado- TSN loop (: 154 ) indexar o buffer através do `NetConvert.ParseUInt 16 / 32 ` (`buffer[posn]`, sem limites verificados — `sys/Net/NetConvert.cs: 30,41 "). "SctpPacket.ParseChunks" (SctpPacket. cs: 195 - 203 ) valida apenas ` chunkLungth >= 4 ` e `posn+chunkLongth <= comprimento`; as contagens dentro do valor nunca são selecionadas. `RTCSctpTransport.DoReceive` chama `SctpPacket.Parse(recvBuffer, 0, bytesRead)` em um reutilizado `recvBuffer = novo byte[ 262144 ]`. ## Impacto `IndexOutOfRangeException` é um `SystemException`, não `ApplicationException`, então o `capture (ApplicationException) {... continue; }` no RTCSctpTransport.cs: 345 é pulado e o controle cai para o genérico ` captura (Excepção) {... break; }` em: 356. O `break` sai do loop de receção, `DoReceive` retorna, e o dedicado `_receiveThread = novo thread(DoReceive)` (: 173, iniciado uma vez) sai sem reiniciar → a associação SCTP e cada canal de dados está permanentemente morto (negação de serviço).
Prova do conceito Um peer WebRTC negociado (post-DTLS) envia um pacote SCTP validado em soma de cheques: 12 -byte cabeçalho comum + um pedaço SACK (tipo 3 ) com ` chunkLength= 16 `, `numGapAckBlocks= 0 xFFFF`, `numDuplicateTSNs= 0 xFFFF`. CRC 32 C é computable com o atacante. O loop de gap- ack atinge o `buffer[ 262144 ]` em um 262144 -byte array (índices válidos) 0.. 262143 ) → `IndexOutOfRangeException`. ## Cadeia de ataque 1. Entrada: o par negociado pós-DTLS envia um pacote SCTP válido em soma de cheques com um pedaço SACK (`chunkLength= 16 `, `numGapAckBlocks= 0 xFFFF`). Guarda: `VerifyChecksum` (CRC 32 C). Convés: CRC 32 C é computable pelo remetente. 2. Processamento: `DoReceive` (RTCSctpTransport.cs: 286 ) lê em reutilizado ` recvBuffer` ( 262144 bytes,: 280 ) → `SctpPacket.Parse(recvBuffer, 0, bytesRead)` (: 302 ) → `ParseChunks` → SACK envio (`SctpChunk.Parse`: 340 - 341 ) → `SctpSackChunk.ParseChunk`. Guarda: "ParseChunks" verifica apenas `chunkLength>= 4 ` e `posn+chunkLongth<=longitude' (SctpPacket. cs: 195 - 203 ). Bypass: ` chunkLength= 16 ` está bem formada; as contagens nunca são validadas. 3. Lava: loop de gap- ack (SctpSackChunk. cs: 146 ) chama `NetConvert.ParseUInt 16 (buffer, reportPosn)` com `reportPosn` começando no `startPosn( 16 )+ FIXED_PARAMETRES( 12 )= 28 `, escalando `+ 4 ` cada iteração. Guard: nenhum na contagem. Convés: `NetConvert.ParseUInt 16 ` (NetConvert.cs: 30 ) índices `buffer[posn]` desmarcados. 4. Impacto: na iteração 65529, `reportPosn = 28 + 65529 * 4 = 262144 ` → `buffer[ 262144 ]` → `IndexOutOfRangeException` → genérico `catcha` no RTCSctpTransport.cs: 356 → `break` → receber saídas de thread, nenhuma associação reiniciar → permanentemente morta. ## Evidência de Bypass - contagem não verificada no SctpSackChunk. cs: 141 - 142; loops em: 146,: 154. - `NetConvert.ParseUInt 16 ` indexação não verificada (NetConvert.cs: 30 ) - "ParseChunks" valida apenas "chunkLength" (SctpPacket. cs: 195 - 203 ) - Matemática OOB: ` 28 + 65535 * 4 = 262168 > 262144 `; buffer é 262144 (`DEFAULT_ADVERTISED_RECEIBIE_WINDOW`, SctpAssociation.cs: 62 ). "numGapAckBlocks" por si só basta — o loop dup- TSN não é necessário. - "DoReceive" catcher divide: recuperable `catcher(ApplicationException)' at: 345 (`continue`) vs genérico `capture(Exception)` em: 356 (`break`); `_ receiveThread` começou uma vez em: 176.
Versão afetada `nuget:SIPSorcery <= 10.0.13 ` (verificado presente na etiqueta de lançamento v 10.0.13 e HEAD da 944543 ). ## Dedup NÃO é uma duplicada do GHSA-qmvg- 569 h- hqrh — essa correção (`fe 5 a 1 Fa`) tocou apenas em `SctpPacket.cs` (o loop infinito de comprimento zero do cursor de fragmentos, CWE- 835 ). Esta é uma leitura distinta fora de limites (CWE- 125 ) em loops de contagem de `SctpSackChunk`, intocados por essa correção. ## Sugestão de correção Validar `startPosn + FIXED_PARAMETERS_LENGUA + numGapAckBlocks* 4 + numDuplicateTSNs* 4 <= posn + blocoLen` antes dos loops, e/ ou fazer com que os limites `NetConvert.Parse*` sejam verificados, e/ ou tratar `IndexOfRangeException`/ `ArgumentException` como recuperable em `DoReceive`.
--- Reportado por **zx (Jace)** — GitHub: @manus-use. Registro de aconselhamento: GHSA- jwjp- 4649 - v 8 JP. Não há nenhum identificador adicional listado. Tempo: GitHub Advisory Database publicou este registro em 2026 - 08 - 12 T 19: 30: 43.000 Z e lista a sua última modificação como 2026 - 08 - 12 T 19: 30: 43.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.
Informações sobre software e versão afetadas: NuGet pacote SIPSorcery — ECOSISTEM: introduzido 0, corrigido 10.0.14. Classificação e evidência: identificadores de fraqueza CWE- 125, CWE- 755. O registro contém 3 suporte de referências nestes tipos: WEB, PACKAGE.