2021. Niu Turns the World. CTF Open Beta-REVESE-wp

En primer lugar, escupemos el campo de entrenamiento de invitados rojos. No hay un pwn para la pregunta. Solo puedo probar Reverse.

CrackMe

  1. Inspección de rutina, sin shell, programa de 32 bits
    Inserte la descripción de la imagen aquí
  2. Ejecute el programa para ver la situación general.
    Inserte la descripción de la imagen aquí
  3. Abra el ida de 32 bits, quiero recuperar la cadena FALSE y encontrar la función clave, pero parece que no puedo encontrarla en la ventana de la cadena. Vaya a la sección rdata (sección de datos de recursos, todos los datos de recursos utilizados por el programa está aquí) y la sección de datos (esta sección Almacene los datos globales del programa, las constantes globales, etc.) Búsquelo y finalmente déjeme encontrar 'FALSE' en la sección rdata
    Inserte la descripción de la imagen aquí
    ctrl + x para encontrar la función que hace referencia a él
int __thiscall sub_401730(CWnd *this)
{
    
    
  int v2; // edi
  HMODULE v3; // eax
  int v4; // edx
  struct CWnd *v5; // eax
  int v6; // esi
  int i; // eax
  int v8; // eax
  CWnd *v9; // eax
  char v11[4]; // [esp+10h] [ebp-1D0h] BYREF
  int v12; // [esp+14h] [ebp-1CCh]
  int v13; // [esp+18h] [ebp-1C8h]
  int v14; // [esp+1Ch] [ebp-1C4h] BYREF
  int v15; // [esp+20h] [ebp-1C0h]
  char v16[396]; // [esp+24h] [ebp-1BCh] BYREF
  int v17[8]; // [esp+1B0h] [ebp-30h]
  int v18; // [esp+1DCh] [ebp-4h]

  v17[0] = 0xE;       #初始化的数据
  v17[1] = 0x28;
  v17[2] = 0xC;
  v17[3] = 0x39;
  v17[4] = 6;
  v17[5] = 5;
  v17[6] = 0x20;
  v17[7] = 0x1F;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
  v2 = 0;
  v18 = 0;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  LOBYTE(v18) = 1;
  v3 = GetModuleHandleW(0);
  v4 = *((unsigned __int8 *)v3 + 1);
  v12 = *(_BYTE *)v3;
  v13 = v4;
  CWnd::UpdateData(this, 1);
  v5 = CWnd::GetDlgItem(this, 1000);
  CWnd::GetWindowTextW(v5);
  v6 = *(_DWORD *)(v14 - 12);
  v15 = 0;
  memset(v16, 0, sizeof(v16));
  if ( v6 > 0 )
  {
    
    
    do
    {
    
    
      *(&v15 + v2) = (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v14, v2);
      ++v2;
    }
    while ( v2 < v6 );
  }
  for ( i = 0; i < v6; ++i )
  {
    
    
    if ( (i & 1) != 0 )
      *(&v15 + i) ^= v13;
    else
      *(&v15 + i) ^= v12;
  }
  v8 = 0;
  if ( v6 <= 0 )
    goto LABEL_14;
  do
  {
    
    
    if ( *(&v15 + v8) != v17[v8] )
      break;
    ++v8;
  }
  while ( v8 < v6 );
  if ( v8 == 8 && v6 == 8 )
  {
    
    
    MessageBoxW(0, L"TRUE", &Caption, 0);
  }
  else
  {
    
    
LABEL_14:
    MessageBoxW(0, L"FALSE", &word_4037A8, 0);
    ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator=(&v14, &unk_4037C0);
    v9 = CWnd::GetDlgItem(this, 1000);
    CWnd::SetWindowTextW(v9);
  }
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  return ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
}

Probablemente inicializamos un dato para nosotros al principio, calculamos i & 1 y descubrimos que está desalineado para realizar operaciones XOR con v13 y v12, por lo que la lógica principal de esta pregunta es realizar operaciones XOR en la desalineación de nuestros datos de entrada con v13 y v12, y finalmente obtenga la matriz inicializada. Siempre que la matriz inicializada tenga XORed con v13 y v12, los valores de entrada correctos
Inserte la descripción de la imagen aquí
v13 y v12 se pueden obtener desde aquí

v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;

La explicación de Baidu Encyclopedia de la función GetModuleHandleW (0) no es muy clara a partir del significado literal. Estaba atrapado aquí en ese momento. Después de depurar con od durante mucho tiempo, no encontré el valor de v13 y v12.
Inserte la descripción de la imagen aquí
Después del juego , Depuro con ida. De acuerdo con la longitud de la matriz de inicialización Es 8, por lo que la longitud de los datos que ingresamos también es 8. Al cambiar, simplemente ingrese una cadena de longitud 8 para
encontrar su valor. La declaración de asignación se encuentra principalmente aquí . Encontré v12 y v13 en la ventana de locales y
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
obtuve v12. Y el valor de v13, puede escribir un script para calcular el código de registro correcto

a=[0x0e,0x28,0x0c,0x39,6,5,0x20,0x1f]

v12=0x4d
v13=0x5a

string=""

for i in range(8):
    if (i&1)!=0:
        string+=chr(a[i]^v13)
    else:
        string+=chr(a[i]^v12)

print(string)

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Debería ser porque no estoy familiarizado con el ensamblaje, por lo que lo uso más fácilmente que od, ida.

Antidebug

  1. Inspección de rutina, programa de 32 bits, sin shell
    Inserte la descripción de la imagen aquí
  2. Ejecute el programa para ver la situación general.
    Inserte la descripción de la imagen aquí
  3. Debido a que es la entrada del cuadro de diálogo, primero use Resource Hacker para encontrar la posición del cuadro de entrada y vea que el ID de control de la clave es 1000
    Inserte la descripción de la imagen aquí
    en ida alt + i, abra el cuadro de búsqueda inmediata, busque 1000 y haga doble clic para
    Inserte la descripción de la imagen aquí
    encontrar el lugar de llamada
    Inserte la descripción de la imagen aquí
    En la función clave, se encuentra que jz y jnz saltan a la misma posición. Inicialmente se sospecha que hay una instrucción de flor que afecta el funcionamiento normal de ida. Nop (ruta clave - > Complete range, pathc is nop) elimina
    Inserte la descripción de la imagen aquí
    el local_401524 al que saltan, preste atención 00401524 es una instrucción de varios bytes, primero use la tecla de método abreviado d para convertirla en datos, luego apáguela y luego convierta la tecla de método abreviado c en el código.
    Después de la modificación,
    Inserte la descripción de la imagen aquí
    puede encontrar la posición de inicio de la función push ebp, haga clic con el botón derecho en la función de crear, luego puede ver que la
    Inserte la descripción de la imagen aquí
    Inserte la descripción de la imagen aquí
    lógica del pseudocódigo f5 es simple, cuando el valor es igual a la entrada de 2,882,395,322 cuando se le solicite corregir
    Inserte la descripción de la imagen aquí
    este problema es investigar una instrucción para gastar

Supongo que te gusta

Origin blog.csdn.net/mcmuyanga/article/details/113745699
Recomendado
Clasificación