Aplicando Instrumentación dinámica al crackMe de Leyer

(1/1)

rub'n:
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.
- Ventajas de esta manera: que tenemos mas desacople, claramente, debemos analizar este .jar u otro, por medio de un decompilador bueno, y en lo posible entender, en dado caso desofuscarlo, etc, muchas comparaciones de password son con ese equals, para los Strings si es igual a otro etc...
- Quizas también con bytebuddy se podria cambiar la condicion, invertirla ? con el operador de negacion ? en este caso como todo esta en el main, no lo c rick...

Código
import...
 
public class CrackMe {
 
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};
 
   static String _$$as_OIsl(String _$s_String_) {
       byte[] _$$d_defaultBytes_ = _$s_String_.getBytes();
       MessageDigest _$$a_algorithm = null;
       try {
           _$$a_algorithm = MessageDigest.getInstance("SHA1");
       }
       catch (NoSuchAlgorithmException noSuchAlgorithmException) {
           // empty catch block
       }
       _$$a_algorithm.reset();
       _$$a_algorithm.update(_$$d_defaultBytes_);
       byte[] messageDigest = _$$a_algorithm.digest();
       StringBuffer hexString = new StringBuffer();
       int _$I_Index = 0;
       while (_$I_Index < messageDigest.length) {
           hexString.append(Integer.toHexString(0xFF & messageDigest[_$I_Index]));
           ++_$I_Index;
       }
       String _$f_Foo_ = messageDigest.toString();
       _$s_String_ = "" + hexString;
       return _$s_String_;
   }
 
   public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
       String _DEFF_$ = "ABDHGS61" + new Random().nextInt(10) + "51129018N00S";
       String _IX$ = "";
       String _DEFF_$2 = "2ODNWOF92H823ONEI2332";
       int _$$2341s = 0;
       boolean _$_$2edwb$ = true;
       block0: while (_$_$2edwb$) {
           int _yx$;
           int _stax$ = new Random().nextInt((int)Math.pow(Integer.parseInt("2ODNWOF92H823ONEI2332".substring(10, 12)), 3.0));
           if (_stax$ != Integer.parseInt(String.valueOf(_DEFF_$.charAt(_yx$ = 8)))) continue;
           int _index$ = _DEFF_$.length();
           while (_index$ > 1) {
               if (_index$ == Integer.parseInt("2ODNWOF92H823ONEI2332".substring(20))) {
                   _IX$ = String.valueOf(_IX$) + _DEFF_$.substring(_DEFF_$.indexOf("0") + 2, _DEFF_$.lastIndexOf("0") - _index$);
                   _$$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;
                   _$_$2edwb$ = false;
                   continue block0;
               }
               --_index$;
           }
       }
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
       final JFrame _$$f_dwquig11__ = new JFrame("Ly-Crackme @Leyer");
       _$$f_dwquig11__.setLayout(new FlowLayout());
       final JPasswordField _$$p_Tetxta1Field_ = new JPasswordField(20);
       _$$f_dwquig11__.getContentPane().add(new JLabel("Key: "));
       _$$f_dwquig11__.getContentPane().add(_$$p_Tetxta1Field_);
       int _$$zaq1I1 = new Random().nextInt(_$$Y_sy76.length + 1);
       JLabel $$l_Label_ = new JLabel("X = " + _$$Y_sy76[_$$zaq1I1]);
       _$$f_dwquig11__.getContentPane().add($$l_Label_);
       _$$f_dwquig11__.setSize(500, 100);
       JButton _$$b__$$hsqqso_ = new JButton("Validar");
       String _$$c_Cor_ = "";
       int _$$i_INDEX_ = 0;
       while (_$$i_INDEX_ < _$$Y_sy76.length) {
           if (_$$Y_sy76[_$$i_INDEX_] == _$$Y_sy76[_$$zaq1I1]) {
               int index = 0;
               while (index < _$$i_INDEX_) {
                   _$$c_Cor_ = String.valueOf(_$$c_Cor_) + String.valueOf((byte)_$$Y_sy76[index]);
                   ++index;
               }
               _$$c_Cor_ = String.valueOf(CrackMe._$$as_OIsl(_$$c_Cor_)) + String.valueOf(Math.pow(_$$2341s, 2.0) / 6.0 - 36.0);
           }
           ++_$$i_INDEX_;
       }
       JLabel _$$s_poqh1120 = new JLabel("");
       _$$f_dwquig11__.getContentPane().add(_$$b__$$hsqqso_);
       final String _$$r_easte = _$$c_Cor_;
       _$$f_dwquig11__.getContentPane().setBackground(new Color(13, 124, 19, 12));
       _$$f_dwquig11__.getContentPane().add(_$$s_poqh1120);
       _$$f_dwquig11__.setResizable(false);
       _$$b__$$hsqqso_.setPreferredSize(new Dimension(120, 25));
       _$$f_dwquig11__.setLocationRelativeTo(null);
       _$$f_dwquig11__.setDefaultCloseOperation(3);
       _$$f_dwquig11__.setVisible(true);
       _$$b__$$hsqqso_.addActionListener(new ActionListener(){
 
           @Override
           public void actionPerformed(ActionEvent $$jawteventActionEvent) {
               String _$$I_pos123 = _$$p_Tetxta1Field_.getText();
               if (_$$I_pos123.equalsIgnoreCase(_$$r_easte)) {
                   JOptionPane.showMessageDialog(_$$f_dwquig11__, "Correcto!");
               } else {
                   JOptionPane.showMessageDialog(_$$f_dwquig11__, "Incorrecto!");
               }
           }
       });
   }
}
 

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
public static void transform(String args, Instrumentation inst) {
       new AgentBuilder.Default()
               .ignore(ElementMatchers.none())
               .disableClassFormatChanges()
               .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
               .with(AgentBuilder.RedefinitionStrategy.Listener.StreamWriting.toSystemError())
               .with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
               .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
               .ignore(ElementMatchers.nameStartsWith("net.bytebuddy."))
               .ignore(ElementMatchers.nameStartsWith("java."))
               .ignore(ElementMatchers.nameStartsWith("javax."))
               .ignore(ElementMatchers.nameStartsWith("sun."))
               .type(ElementMatchers.nameContains("CrackMe"))
               .transform((builder, typeDescription, classLoader, module, protectionDomain) ->
                       builder.visit(Advice.to(StringEqualsAdvice.class)
                               .on(ElementMatchers.named("actionPerformed")))
               )
               .installOn(inst);
 
       System.out.println("[+] Interceptor instalado en clases CrackMe");
       System.out.flush();
   }
}
 

Pues resulta que podemos interceptar la clase CrackMe y el botón que hace la comparación del 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
java -javaagent:agent-1.0.0.jar -jar Ly-CrackME.jar <1>
Execute premain method
&#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;
&#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;
&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608; Key: &#9608;&#9608;&#9608;                                       &#9608;&#9608;&#9608;&#9608;&#9608;&#9608;&#9608;
&#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;
&#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;
&#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;
&#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;
&#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;
 
Starting monkey patching :D by rubn0x52.com
 
[+] Interceptor instalado en clases CrackMe
 
[*] Botón Validar presionado!
Clave encontrada
Campo: val$_$$r_easte
Clave: 6ff173f14d9384c6b897b4be810e5699ca997e18.0 <2>
 
[*] Botón Validar presionado!
Clave encontrada
Campo: val$_$$r_easte
 


- 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
java -jar LyCrackME.jar

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

Código
rubn > jps                                      
4113 Main
163776 RemoteMavenServer36
212017 jar
4555 SonarLintServerCli
34763 RemoteMavenServer36
12718 RemoteMavenServer36
212061 Jps
171085 java
rubn > java -jar patch-lycrackme-1.0.0.jar 212017
 
rubn
https://rubn0x52.com
Attached to target jvm correctly
 

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
package com.prueba.lycrackme.advice;
 
import net.bytebuddy.asm.Advice;
 
public class StringEqualsAdvice {
 
   @Advice.OnMethodEnter
   public static void enter(@Advice.This Object thiz) {
       System.out.println("\n[*] Botón Validar presionado!");
       System.out.flush();
       try {
           // Extraer todos los campos del ActionListener anónimo
           java.lang.reflect.Field[] fields = thiz.getClass().getDeclaredFields();
           for (java.lang.reflect.Field field : fields) {
               field.setAccessible(true);
               Object value = field.get(thiz);
               if (value instanceof String) {
                   String str = (String) value;
                   // La clave correcta será un string largo (hash SHA1 + número)
                   if (field.getName().contains("easte")) {
                       System.out.println("Clave encontrada");
                       System.out.println("Campo: " + field.getName());
                       System.out.println("Clave: " + str);
                       System.out.flush();
                   }
               }
           }
       } catch (Exception e) {
           System.err.println("[!] Error extrayendo campos: " + e.getMessage());
           e.printStackTrace();
       }
   }
 
}
 

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

Navegación

[0] Índice de Mensajes