* Trabalha numa **empresa de cibersegurança**? Quer ver a sua **empresa anunciada no HackTricks**? ou quer ter acesso à **versão mais recente do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs exclusivos**](https://opensea.io/collection/the-peass-family)
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
A exploração do JDWP baseia-se na **falta de autenticação e criptografia do protocolo**. Geralmente é encontrado na **porta 8000**, mas outras portas são possíveis. A conexão inicial é feita enviando um "JDWP-Handshake" para a porta alvo. Se um serviço JDWP estiver ativo, ele responde com a mesma string, confirmando sua presença. Este handshake funciona como um método de fingerprinting para identificar serviços JDWP na rede.
Em termos de identificação de processos, procurar pela string "jdwk" em processos Java pode indicar uma sessão JDWP ativa.
A ferramenta de escolha é [jdwp-shellifier](https://github.com/hugsy/jdwp-shellifier). Você pode usá-la com diferentes parâmetros:
Descobri que o uso de `--break-on 'java.lang.String.indexOf'` torna o exploit mais **estável**. E se você tiver a chance de fazer upload de um backdoor para o host e executá-lo em vez de executar um comando, o exploit será ainda mais estável.
**Java Platform Debug Architecture (JPDA)**: JDWP é um componente do sistema global de depuração Java, chamado Java Platform Debug Architecture (JPDA)\[2]. A seguir, um diagrama da arquitetura geral:
O Debuggee consiste em uma JVM multi-threaded executando nossa aplicação alvo. Para ser remotamente depurável, a instância da JVM deve ser explicitamente iniciada com a opção -Xdebug passada na linha de comando, bem como a opção -Xrunjdwp (ou -agentlib). Por exemplo, iniciar um servidor Tomcat com depuração remota ativada seria assim:
Como mostrado no diagrama da arquitetura, o Java Debug Wire Protocol é o elo central entre o Debugger e a instância da JVM. Observações sobre o protocolo incluem:
* É principalmente síncrono. O debugger envia um comando pelo JDWP e espera receber uma resposta. No entanto, alguns comandos, como Eventos, não esperam uma resposta síncrona. Eles enviarão uma resposta quando condições específicas forem atendidas. Por exemplo, um BreakPoint é um Evento.
Todas essas observações fazem total sentido, já que estamos falando de um protocolo de depuração. No entanto, quando tal serviço é exposto a uma rede hostil ou está voltado para a Internet, as coisas podem dar errado.\
**Handshake**: JDWP dita\[9] que a comunicação deve ser iniciada por um simples handshake. Após uma conexão TCP bem-sucedida, o Debugger (cliente) envia a string ASCII de 14 caracteres “JDWP-Handshake”. O Debuggee (servidor) responde a esta mensagem enviando exatamente a mesma string. O seguinte rastreamento scapy\[3] mostra o handshake inicial de duas vias:
root:\~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:\~/tools/scapy-hg # ./run\_scapy
Um auditor de segurança experiente já pode ter percebido que tal handshake simples oferece uma maneira de descobrir facilmente serviços JDWP ativos na Internet. Basta enviar uma sonda simples e verificar a resposta específica. Mais interessante ainda, um comportamento foi observado no IBM Java Development Kit ao escanear com o ShodanHQ\[4] com o servidor "falando" primeiro com o mesmo banner mencionado. Como consequência, existe uma maneira totalmente passiva de descobrir um serviço JDWP ativo (isso é abordado mais adiante neste artigo com a ajuda do (in)famoso Shodan).\
**Comunicação**: JDWP define mensagens\[10] envolvidas na comunicação entre o Debugger e o Debuggee. As mensagens seguem uma estrutura simples, definida da seguinte forma: 
Os campos Length e Id são autoexplicativos. O campo Flag é usado apenas para distinguir pacotes de solicitação de respostas, com um valor de 0x80 indicando um pacote de resposta. O campo CommandSet define a categoria do Comando, conforme mostrado na tabela a seguir.\
* VirtualMachine/IDSizes define o tamanho das estruturas de dados manipuladas pela JVM. Esta é uma das razões pelas quais o script nmap jdwp-exec.nse\[11] não funciona, pois o script usa tamanhos codificados.
* ClassType/InvokeMethod permite invocar uma função estática.
* ObjectReference/InvokeMethod permite invocar uma função de um objeto instanciado na JVM.
* StackFrame/(Get|Set)Values fornece capacidades de empilhar/desempilhar da pilha de threads.
* Event/Composite força a JVM a reagir a comportamentos específicos declarados por este comando. Este comando é uma chave importante para fins de depuração, pois permite, entre muitas outras coisas, definir breakpoints, avançar passo a passo pelos threads durante a execução e ser notificado ao acessar/modificar valores da mesma maneira que GDB ou WinDBG.
JDWP não só permite acessar e invocar objetos já residentes na memória, mas também permite criar ou sobrescrever dados.
Como vimos, JDWP fornece comandos embutidos para carregar classes arbitrárias na memória da JVM e invocar bytecode já existente e/ou recém-carregado. A próxima seção cobrirá as etapas para criar código de exploração em Python, que se comporta como uma implementação parcial de uma interface JDI para ser o mais confiável possível. A principal razão para este script de exploit independente é que, como pentester, gosto de exploits "head-shot". Ou seja, quando sei com certeza que um ambiente/aplicativo/protocolo é vulnerável, quero ter minha ferramenta pronta para explorá-lo imediatamente (ou seja, sem PoC, que basicamente é a única coisa que existia até agora). Então, agora que cobrimos a teoria, vamos para a implementação prática. Ao enfrentar um serviço JDWP aberto, a execução de comandos arbitrários está a apenas cinco passos de distância (ou com este exploit, apenas um comando de linha de distância). Veja como seria: 1. Obter referência do Java RuntimeA JVM manipula objetos através de suas referências. Por essa razão, nosso exploit deve primeiro obter a referência para a classe java.lang.Runtime. Dessa classe, precisamos da referência para o método getRuntime(). Isso é feito buscando todas as classes (pacote AllClasses) e todos os métodos na classe que estamos procurando (pacote ReferenceType/Methods). 2. Configurar breakpoint e aguardar notificação (chamadas assíncronas)Este é o ponto chave do nosso exploit. Para invocar código arbitrário, precisamos estar em um contexto de thread em execução. Para fazer isso, um hack é configurar um breakpoint em um método que se sabe ser chamado em tempo de execução. Como visto anteriormente, um breakpoint no JDI é um evento assíncrono cujo tipo é definido como BREAKPOINT(0x02). Quando atingido, a JVM envia um pacote EventData para nosso debugger, contendo nosso ID de breakpoint e, mais importante, a referência para o thread que o atingiu.\
Portanto, é uma boa ideia configurá-lo em um método frequentemente chamado, como java.net.ServerSocket.accept(), que provavelmente será chamado toda vez que o servidor receber uma nova conexão de rede. No entanto, deve-se ter em mente que poderia ser qualquer método existente em tempo de execução. 3. Alocar um objeto Java String no Runtime para transportar o payloadVamos executar código no tempo de execução da JVM, então todos os nossos dados manipulados (como string) devem existir no tempo de execução da JVM (ou seja, possuir uma referência de tempo de execução). Isso é feito de maneira bastante simples, enviando um comando CreateString.
4\. Obter objeto Runtime a partir do contexto de breakpointNeste ponto, temos quase todos os elementos de que precisamos para uma exploração bem-sucedida e confiável. O que nos falta é uma referência ao objeto Runtime. Obtê-la é fácil, e podemos simplesmente executar no tempo de execução da JVM o método estático java.lang.Runtime.getRuntime()\[8] enviando um pacote ClassType/InvokeMethod e fornecendo as referências da classe Runtime e do thread. 5. Procurar e invocar o método exec() na instância RuntimeO passo final é simplesmente procurar o método exec() no objeto estático Runtime obtido no passo anterior e invocá-lo (enviando um pacote ObjectReference/InvokeMethod) com o objeto String que criamos no terceiro passo. 
O exploit final utiliza essas técnicas, adiciona algumas verificações e envia sinais de suspensão/retomada para causar o mínimo de interrupção possível (é sempre melhor não quebrar a aplicação em que você está trabalhando, certo?). Ele atua em dois modos:
* O modo "Padrão" é totalmente não intrusivo e simplesmente executa código Java para obter informações do sistema local (perfeito para um PoC para um cliente).
* Passando a opção "cmd", executa um comando do sistema no host remoto e, portanto, é mais intrusivo. O comando é realizado com os privilégios com os quais a JVM está sendo executada.
Como o Java é independente de plataforma por design, comandos podem ser executados em qualquer sistema operacional que o Java suporte. Bem, isso é na verdade uma boa notícia para nós, pentesters: **serviço JDWP aberto significa RCE confiável**. Até agora, tudo bem.
De fato, o JDWP é bastante utilizado no mundo das aplicações Java. Pentesters podem, no entanto, não vê-lo com tanta frequência ao realizar avaliações remotas, pois firewalls devem (e deveriam) bloquear principalmente a porta em que está sendo executado. Mas isso não significa que o JDWP não possa ser encontrado na natureza:
* No momento em que este artigo foi escrito, uma rápida pesquisa no ShodanHQ\[4] revela imediatamente cerca de 40 servidores enviando o handshake do JDWP:
* Fazer masscan na Internet procurando por portas específicas (tcp/8000, tcp/8080, tcp/8787, tcp/5005) revelou muitos hosts (que não podem ser relatados aqui) respondendo ao handshake inicial.
* Aplicações "Enterprise" foram encontradas na natureza executando um serviço JDWP \*por padrão\* (encontrar o número da porta real fica como um exercício para o leitor curioso).
Estas são apenas algumas maneiras de descobrir serviços JDWP abertos na Internet. Isso é um ótimo lembrete de que as aplicações devem passar regularmente por revisões de segurança completas, ambientes de produção devem ter qualquer funcionalidade de depuração desativada e firewalls devem ser configurados para restringir o acesso apenas aos serviços necessários para a operação normal. Permitir que qualquer pessoa se conecte a um serviço JDWP é exatamente o mesmo que permitir uma conexão a um serviço gdbserver (de uma maneira que pode ser mais estável). Espero que tenham gostado de ler este artigo tanto quanto eu gostei de brincar com o JDWP. A todos vocês, poderosos piratas, feliz conquista do JDWP!!
* Você trabalha em uma **empresa de cibersegurança**? Quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **versão mais recente do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).