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.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
WebLogic-Shiro-shell — Exploração de vulnerabilidade de desserialização do Shiro rememberMe usando CVE-2020-2883 no WebLogic, registro com um clique de shell de memória via filtro do AntSword | Kitploit
Ferramentas/GitHubGitHub/y4er/weblogic-shiro-shell
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoAprendizado e EducaçãoDesenvolvimento de PayloadsExploração de Binários
GitHuby4er/weblogic-shiro-shell

WebLogic-Shiro-shell

Exploração de vulnerabilidade de desserialização do Shiro rememberMe usando CVE-2020-2883 no WebLogic, registro com um clique de shell de memória via filtro do AntSword

Ver Repositório
5316012há 6 anosRevisado pelo Kitploit

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

Compartilhamento de Técnicas de Desserialização em Java

Os tópicos abordados nesta apresentação incluem:

  1. Fundamentos de serialização e desserialização em Java
  2. Por que vulnerabilidades ocorrem durante a desserialização?
  3. Reflexão em Java
  4. ysoserial CommonsCollections2, CommonsCollections5
  5. Vários métodos de carregamento de classes com Java ClassLoader
  6. WebLogic CVE-2020-2555 CVE-2020-2883 RCE
  7. Shiro-550 rememberMe RCE de desserialização devido à codificação fixa
  8. WebLogic + Shiro desserialização para registro de filter memory shell com um clique

Fundamentos de serialização e desserialização em Java

Serialização em Java é o processo de converter objetos Java em uma sequência de bytes para facilitar o armazenamento em memória, arquivos ou banco de dados. O método writeObject() da classe ObjectOutputStream pode realizar a serialização, convertendo objetos Java em sequência de bytes.

Desserialização em Java é o processo de restaurar uma sequência de bytes para um objeto Java. O método readObject() da classe ObjectInputStream é usado para desserialização.

Um exemplo simples, veja o código SerializeAndDeserialize ps: preste atenção especial na conversão forçada de tipos no código```java package org.chabug.demo;

import org.chabug.entity.Dog; import org.chabug.entity.Person; import org.chabug.util.Serializables;

/* 这个例子是为了证明只要实现了Serializable接口的类都可以被序列化 并且Java内置的几大数据类型也可被序列化,因为他们都继承了Object类 */

public class SerializeAndDeserialize {

public static void main(String[] args) throws Exception {
    byte[] bytes;
    String s1 = "I'm a String Object....";
    bytes = Serializables.serializeToBytes(s1);
    Object o1 = Serializables.deserializeFromBytes(bytes);
    System.out.println(o1);

    String[] s2 = new String[]{"tom", "bob", "jack"};
    bytes = Serializables.serializeToBytes(s2);
    String[] o2 = (String[])Serializables.deserializeFromBytes(bytes);
    System.out.println(o2);

    int i = 123;
    bytes = Serializables.serializeToBytes(i);
    int o3 = (Integer) Serializables.deserializeFromBytes(bytes);
    System.out.println(o3);

    // 一只名叫woody的狗
    Dog dog = new Dog();
    dog.setName("woody");

    // tom
    Person tom = new Person();
    tom.setAge(14);
    tom.setName("tom");
    tom.setSex("男");
    tom.setDog(dog);

    bytes = Serializables.serializeToBytes(tom);
    Person o = (Person) Serializables.deserializeFromBytes(bytes);
    System.out.println(o);

}

}

String, Integer, array, Object e outros tipos de dados integrados do Java podem ser serializados. As classes Person e Dog que escrevemos podem ser serializadas e desserializadas desde que implementem a interface Serializable.

## Por que ocorre uma vulnerabilidade durante a desserialização?

Vejamos um trecho de código. Agora, existe uma classe de entidade maliciosa EvilClass```java
package org.chabug.entity;

import java.io.ObjectInputStream;
import java.io.Serializable;

public class EvilClass implements Serializable {
    String name;

    public EvilClass() {
        System.out.println(this.getClass() + "的EvilClass()构造方法被调用!!!!!!");
    }

    public EvilClass(String name) {
        System.out.println(this.getClass() + "的EvilClass(String name)构造方法被调用!!!!!!");
        this.name = name;
    }

    public String getName() {
        System.out.println(this.getClass() + "的getName被调用!!!!!!");
        return name;
    }

    public void setName(String name) {
        System.out.println(this.getClass() + "的setName被调用!!!!!!");
        this.name = name;
    }

    @Override
    public String toString() {
        System.out.println(this.getClass() + "的toString()被调用!!!!!!");
        return "EvilClass{" +
                "name='" + getName() + '\'' +
                '}';
    }

    private void readObject(ObjectInputStream in) throws Exception {
        //执行默认的readObject()方法
        in.defaultReadObject();
        System.out.println(this.getClass() + "readObject()被调用!!!!!!");
        Runtime.getRuntime().exec(new String[]{"cmd", "/c", name});
    }
}

Seu readObject contém código que executa comandos Runtime.getRuntime().exec(new String[]{"cmd", "/c", name}), onde o parâmetro name é o comando a ser executado. Então podemos construir um objeto malicioso, atribuir ao seu atributo name o comando a ser executado, e quando a desserialização acionar o readObject, ocorrerá RCE. Como segue:```java package org.chabug.demo;

import org.chabug.entity.EvilClass; import org.chabug.util.Serializables;

public class EvilSerialize { public static void main(String[] args) throws Exception { EvilClass evilObj = new EvilClass(); evilObj.setName("calc"); byte[] bytes = Serializables.serializeToBytes(evilObj); EvilClass o = (EvilClass) Serializables.deserializeFromBytes(bytes); System.out.println(o); } }

![image-20200822105256120](https://assets.kitploit.com/production/public/readmes/21799/7f07c0c8196e56e1d554bce64f73f069bdd3e589a3302936c831903e5f7e5539.png)

Agora sabemos como a desserialização pode levar a RCE, mas no desenvolvimento real não é possível escrever diretamente assim, então isso envolve a busca por cadeias de exploração. Uma vulnerabilidade de desserialização requer três coisas:

1. Ponto de entrada da desserialização (source)
2. Método alvo (sink)
3. Cadeia de gadgets (gadget chain)

Observando com atenção o resultado de saída na imagem acima, não apenas o método `readObject` é acionado, mas também `toString()`, construtor sem parâmetros, `set` e `get`. Portanto, na busca prática por cadeias de exploração, não é necessário focar apenas no método `readObject()`.

Em seguida, precisamos entender o conceito de **reflexão**. Mencionamos anteriormente o problema de **conversão de tipo forçada**. No desenvolvimento real, dentro do `readObject`, há processamento lógico: quando o tipo de dados específico do objeto de entrada é desconhecido, a reflexão é usada para determinar e invocar. E a reflexão é um meio importante para alcançarmos RCE.

## Reflexão em Java

O que é reflexão? A palavra "reflexão" contém o prefixo "re-". Para explicar a reflexão, precisamos começar pela "reflexão direta". Veja o código. Esta é minha classe de entidade.```java
package org.chabug.entity;

import java.io.IOException;

public class ReflectionClass {
    String name;

    public ReflectionClass(String name) {
        this.name = name;
    }

    public ReflectionClass() {
    }

    public String say() {
        return this.name;
    }

    private void evil(String cmd) {
        try {
            Runtime.getRuntime().exec(new String[]{"cmd","/c",cmd});
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "ReflectionClass{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Escrita normal```java package org.chabug.demo;

import org.chabug.entity.ReflectionClass;

public class ReflectionDemo { public static void main(String[] args) { ReflectionClass demo = new ReflectionClass(); demo.setName("hello"); System.out.println(demo.say()); // demo.evil("calc"); // 不能够调用private方法 } }

Muito simples: cria-se uma instância de `ReflectionClass` com `new` e depois, através dessa instância, invocam-se os métodos pertencentes a ela — isso é "reflexão direta". Mas o que fazer quando você não sabe o nome da classe ao usar `new`? E como invocar métodos protegidos por `private`? É aí que a reflexão mostra o seu valor. Veja o código a seguir:```java
package org.chabug.demo;

import org.chabug.entity.ReflectionClass;

import java.lang.reflect.Method;
Baixar ferramenta