elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Ingeniería Inversa (Moderadores: karmany, .:UND3R:., MCKSys Argentina)
| | |-+  Aplicando Instrumentación dinámica al crackMe de Leyer
0 Usuarios y 3 Visitantes están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Aplicando Instrumentación dinámica al crackMe de Leyer  (Leído 168 veces)
rub'n


Desconectado Desconectado

Mensajes: 1.223


(e -> λ("live now")); tatuar -> λ("α");


Ver Perfil WWW
Aplicando Instrumentación dinámica al crackMe de Leyer
« en: Hoy a las 02:08 »

Hola,

El crackMe de leyer resuelto medianamente en el 2017 por mi Solución lycrackme, veo una mejor manera de hacerlo con Instrumentación dinamica usando el api de ByteBuddy, para construir un agente y adjuntarlo en tiempo de ejecución al crackME o proceso de este.

- Importante: para usar el APi de Java de instrumentación, estoy usando la JDK 8, dado en contiene el tools.jar, si o si es necesario para poder crear el agente, abria que investigar como hacerlo con versiones mas nuevas de Java.
- El código del crackME para que no se pierda, y recordarlo, leyer me odiara ya...
- Aún asi es un escenario fácil ya que el código no esta ni cifrado, ni ofuscado, podemos leer las variables incluso, decompilar también el .jar del crackME, o sea ventajas, en otros escenarios, un decompilador de Java con un .jar ofuscado no lograria decompilar bien y se confundiría.

Código
  1. import...
  2.  
  3. public class CrackMe {
  4.  
  5. static int[] _$$Y_sy76 = new int[]{7414755, 3219665, 175186692, 136322726, 136419744, 4066036, 15685602, 103481, 8331326, 14522496, 254443529, 117440530, 0x100000, 10066673, 0xEEE122, 0x421442, 1183806, 11019024, 140529167, 118489840, 19071234, 0xF00004, 3109537, 594494, 7406141, 9476832, 18812418, 9969838, 34803714, 3298805, 2302368, 15368608, 8916253, 9445024, 51519491, 31, 241696768, 7414181, 2299045, 39441, 9539087, 16392240, 0x9090090, 117641473, 258080912, 16115104, 0x120120, 0x10101A, 1183501, 7413822, 236060690, 257294849, 125830118, 66016, 8983278, 624289, 16609425, 14844138, 27270816, 239404033, 51389454, 7414690, 593951, 7709524, 9969409, 9847050, 118646528, 158482433, 0x1110011, 2299045, 2299045, 3739700};
  6.  
  7.    static String _$$as_OIsl(String _$s_String_) {
  8.        byte[] _$$d_defaultBytes_ = _$s_String_.getBytes();
  9.        MessageDigest _$$a_algorithm = null;
  10.        try {
  11.            _$$a_algorithm = MessageDigest.getInstance("SHA1");
  12.        }
  13.        catch (NoSuchAlgorithmException noSuchAlgorithmException) {
  14.            // empty catch block
  15.        }
  16.        _$$a_algorithm.reset();
  17.        _$$a_algorithm.update(_$$d_defaultBytes_);
  18.        byte[] messageDigest = _$$a_algorithm.digest();
  19.        StringBuffer hexString = new StringBuffer();
  20.        int _$I_Index = 0;
  21.        while (_$I_Index < messageDigest.length) {
  22.            hexString.append(Integer.toHexString(0xFF & messageDigest[_$I_Index]));
  23.            ++_$I_Index;
  24.        }
  25.        String _$f_Foo_ = messageDigest.toString();
  26.        _$s_String_ = "" + hexString;
  27.        return _$s_String_;
  28.    }
  29.  
  30.        String _DEFF_$ = "ABDHGS61" + new Random().nextInt(10) + "51129018N00S";
  31.        String _IX$ = "";
  32.        String _DEFF_$2 = "2ODNWOF92H823ONEI2332";
  33.        int _$$2341s = 0;
  34.        boolean _$_$2edwb$ = true;
  35.        block0: while (_$_$2edwb$) {
  36.            int _yx$;
  37.            int _stax$ = new Random().nextInt((int)Math.pow(Integer.parseInt("2ODNWOF92H823ONEI2332".substring(10, 12)), 3.0));
  38.            if (_stax$ != Integer.parseInt(String.valueOf(_DEFF_$.charAt(_yx$ = 8)))) continue;
  39.            int _index$ = _DEFF_$.length();
  40.            while (_index$ > 1) {
  41.                if (_index$ == Integer.parseInt("2ODNWOF92H823ONEI2332".substring(20))) {
  42.                    _IX$ = String.valueOf(_IX$) + _DEFF_$.substring(_DEFF_$.indexOf("0") + 2, _DEFF_$.lastIndexOf("0") - _index$);
  43.                    _$$2341s = (int)Math.pow(Integer.parseInt(_IX$), 2.0) / Integer.parseInt(_DEFF_$.substring(_DEFF_$.lastIndexOf("1") + 1, _DEFF_$.lastIndexOf("N"))) + Integer.parseInt(_DEFF_$.substring(11, 13)) - 2;
  44.                    _$_$2edwb$ = false;
  45.                    continue block0;
  46.                }
  47.                --_index$;
  48.            }
  49.        }
  50.        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  51.        final JFrame _$$f_dwquig11__ = new JFrame("Ly-Crackme @Leyer");
  52.        _$$f_dwquig11__.setLayout(new FlowLayout());
  53.        final JPasswordField _$$p_Tetxta1Field_ = new JPasswordField(20);
  54.        _$$f_dwquig11__.getContentPane().add(new JLabel("Key: "));
  55.        _$$f_dwquig11__.getContentPane().add(_$$p_Tetxta1Field_);
  56.        int _$$zaq1I1 = new Random().nextInt(_$$Y_sy76.length + 1);
  57.        JLabel $$l_Label_ = new JLabel("X = " + _$$Y_sy76[_$$zaq1I1]);
  58.        _$$f_dwquig11__.getContentPane().add($$l_Label_);
  59.        _$$f_dwquig11__.setSize(500, 100);
  60.        JButton _$$b__$$hsqqso_ = new JButton("Validar");
  61.        String _$$c_Cor_ = "";
  62.        int _$$i_INDEX_ = 0;
  63.        while (_$$i_INDEX_ < _$$Y_sy76.length) {
  64.            if (_$$Y_sy76[_$$i_INDEX_] == _$$Y_sy76[_$$zaq1I1]) {
  65.                int index = 0;
  66.                while (index < _$$i_INDEX_) {
  67.                    _$$c_Cor_ = String.valueOf(_$$c_Cor_) + String.valueOf((byte)_$$Y_sy76[index]);
  68.                    ++index;
  69.                }
  70.                _$$c_Cor_ = String.valueOf(CrackMe._$$as_OIsl(_$$c_Cor_)) + String.valueOf(Math.pow(_$$2341s, 2.0) / 6.0 - 36.0);
  71.            }
  72.            ++_$$i_INDEX_;
  73.        }
  74.        JLabel _$$s_poqh1120 = new JLabel("");
  75.        _$$f_dwquig11__.getContentPane().add(_$$b__$$hsqqso_);
  76.        final String _$$r_easte = _$$c_Cor_;
  77.        _$$f_dwquig11__.getContentPane().setBackground(new Color(13, 124, 19, 12));
  78.        _$$f_dwquig11__.getContentPane().add(_$$s_poqh1120);
  79.        _$$f_dwquig11__.setResizable(false);
  80.        _$$b__$$hsqqso_.setPreferredSize(new Dimension(120, 25));
  81.        _$$f_dwquig11__.setLocationRelativeTo(null);
  82.        _$$f_dwquig11__.setDefaultCloseOperation(3);
  83.        _$$f_dwquig11__.setVisible(true);
  84.        _$$b__$$hsqqso_.addActionListener(new ActionListener(){
  85.  
  86.            @Override
  87.            public void actionPerformed(ActionEvent $$jawteventActionEvent) {
  88.                String _$$I_pos123 = _$$p_Tetxta1Field_.getText();
  89.                if (_$$I_pos123.equalsIgnoreCase(_$$r_easte)) {
  90.                    JOptionPane.showMessageDialog(_$$f_dwquig11__, "Correcto!");
  91.                } else {
  92.                    JOptionPane.showMessageDialog(_$$f_dwquig11__, "Incorrecto!");
  93.                }
  94.            }
  95.        });
  96.    }
  97. }
  98.  

Esta es la manera en que byteBuddy nos permite crear un agente usando su DSL (domain specific language) si, un pedaso de Builder gigantesco.

Código
  1. public static void transform(String args, Instrumentation inst) {
  2.        new AgentBuilder.Default()
  3.                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
  4.                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
  5.                .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
  6.                .disableClassFormatChanges()
  7.                .ignore(ElementMatchers.nameStartsWith("net.bytebuddy."))
  8.                .ignore(ElementMatchers.nameStartsWith("java."))
  9.                .ignore(ElementMatchers.nameStartsWith("javax."))
  10.                .ignore(ElementMatchers.nameStartsWith("sun."))
  11.                .type(ElementMatchers.nameContains("CrackMe"))
  12.                .transform((builder, typeDescription, classLoader, module, protectionDomain) ->
  13.                        builder.visit(Advice.to(StringEqualsAdvice.class)
  14.                                .on(ElementMatchers.named("actionPerformed")))
  15.                )
  16.                .installOn(inst);
  17.  
  18.        System.out.println("[+] Interceptor instalado en clases CrackMe");
  19.        System.out.flush();
  20.    }
  21. }
  22.  

Pues resulta que podemos interceptar la clase CrackMe y el botón que hace la comparación de input con la key, además byteBuddy necesita un Advice, que lo llamo StringEqualsAdvice

- Aplicando instrumentación estática

Aquí por medio del APi de Java de Instrumentación, cuando generamos nuestro agente, y lo ejecutamos como el modo siguiente, el método premain es el que se va a disparar esta vez.

Código
  1. java -javaagent:agent-1.0.0.jar -jar Ly-CrackME.jar <1>
  2. Execute premain method
  3. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608; Ly-Crackme @Leyer &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9619;&#9608;
  4. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9619;&#9619;&#9619;&#9619;&#9619;&#9608;&#9619;&#9619;&#9619;&#9618;&#9619;&#9619;&#9618;&#9619;&#9619;&#9619;&#9619;&#9619;&#9619;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9608;&#9608;&#9608;&#9619;&#9608;&#9608;
  5. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608; Key: &#9608;&#9608;&#9608;                                       &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  6. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9618;&#9617;&#9617;&#9618;&#9619;&#9619;&#9619;&#9608; X=231231321 &#9608;&#9608;&#9608;(Validar)&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  7. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9608;&#9608;&#9608;&#9619;&#9619;&#9608;&#9608;&#9608;&#9619;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  8. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9619;&#9618;&#9619;&#9619;&#9608;&#9619;&#9617;&#9618;&#9618;&#9618;&#9618;&#9618;&#9619;&#9619;&#9618;&#9618;&#9608;&#9619;&#9619;&#9619;&#9619;&#9618;&#9618;&#9618;&#9618;&#9618;&#9618;&#9619;&#9619;&#9619;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  9. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  10. &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
  11.  
  12. Starting monkey patching :D by rubn0x52.com
  13.  
  14. [+] Interceptor instalado en clases CrackMe
  15.  
  16. [*] Botón Validar presionado!
  17. Clave encontrada
  18. Campo: val$_$$r_easte
  19. Clave: 6ff173f14d9384c6b897b4be810e5699ca997e18.0 <2>
  20.  
  21. [*] Botón Validar presionado!
  22. Clave encontrada
  23. Campo: val$_$$r_easte
  24.  



- Aplicando instrumentación dinámica

Para el adjuntado dinámico, necesitamos el PID del crackME, por lo tanto lo ejecutamos con el tipico

Código
  1. java -jar LyCrackME.jar

Ahora extraemos el PID con el comando jps como lo siguiente:

Código
  1. rubn > jps                                      
  2. 4113 Main
  3. 163776 RemoteMavenServer36
  4. 212017 jar
  5. 4555 SonarLintServerCli
  6. 34763 RemoteMavenServer36
  7. 12718 RemoteMavenServer36
  8. 212061 Jps
  9. 171085 java
  10. rubn > java -jar patch-lycrackme-1.0.0.jar 212017
  11.  
  12. rubn
  13. https://rubn0x52.com
  14. Attached to target jvm correctly
  15.  

La linea 10, es como ejecutamos el agente.

El pid es 212017 del crackME, luego pobramos a introducir en el input del crackME y en la consola, el Agente interceptara el click en el botón, más precisamente el método llamado actionListener


Aqui entra en juego el Advice previamente comentado

Código
  1. package com.prueba.lycrackme.advice;
  2.  
  3. import net.bytebuddy.asm.Advice;
  4.  
  5. public class StringEqualsAdvice {
  6.  
  7.    @Advice.OnMethodEnter
  8.    public static void enter(@Advice.This Object thiz) {
  9.        System.out.println("\n[*] Botón Validar presionado!");
  10.        System.out.flush();
  11.        try {
  12.            // Extraer todos los campos del ActionListener anónimo
  13.            java.lang.reflect.Field[] fields = thiz.getClass().getDeclaredFields();
  14.            for (java.lang.reflect.Field field : fields) {
  15.                field.setAccessible(true);
  16.                Object value = field.get(thiz);
  17.                if (value instanceof String) {
  18.                    String str = (String) value;
  19.                    // La clave correcta será un string largo (hash SHA1 + número)
  20.                    if (field.getName().contains("easte")) {
  21.                        System.out.println("Clave encontrada");
  22.                        System.out.println("Campo: " + field.getName());
  23.                        System.out.println("Clave: " + str);
  24.                        System.out.flush();
  25.                    }
  26.                }
  27.            }
  28.        } catch (Exception e) {
  29.            System.err.println("[!] Error extrayendo campos: " + e.getMessage());
  30.            e.printStackTrace();
  31.        }
  32.    }
  33.  
  34. }
  35.  

Entonces podemos recorrer por todos los campos, y machear por uno que se llama _$$r_easte línea 20, que es el que contiene la key.





- He generado una release con el agente.

- https://github.com/rucko24/Instrumentacion-con-bytebuddy/releases/tag/1.0.3
- source: https://github.com/rucko24/Instrumentacion-con-bytebuddy/tree/1.0.3/patch-lycrackme
« Última modificación: Hoy a las 13:43 por rub'n » En línea

rubn0x52.com KNOWLEDGE  SHOULD BE FREE.
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen king
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
instrumentacion para un termopar
Electrónica
gagodu 2 2,845 Último mensaje 4 Junio 2007, 21:38 pm
por d33p57r1k3
Aplicando Reshack
Scripting
Bartu 0 3,359 Último mensaje 26 Diciembre 2008, 00:56 am
por Bartu
Petición libro de instrumentación
Electrónica
Hearts 0 3,317 Último mensaje 7 Junio 2010, 13:50 pm
por Hearts
Entendiendo y aplicando DSPlit (By 2Fac3R)
Análisis y Diseño de Malware
2Fac3R 0 2,864 Último mensaje 16 Septiembre 2011, 20:46 pm
por 2Fac3R
[Planificación] Concurso Tu Crackme Contra Mi Mejor Crackme
Ingeniería Inversa
Flamer 6 5,639 Último mensaje 17 Abril 2016, 03:45 am
por Flamer
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines