Affichage des articles dont le libellé est ida. Afficher tous les articles
Affichage des articles dont le libellé est ida. Afficher tous les articles

mercredi 4 juillet 2012

NDH 2k12 - Lost USB key - 1000pts

Un autre crackme, Windows cette fois-ci.

1.       What
On a un fichier « crackme.exe » qui demande un mot de passe …
Voici ce que PeID en pense :



Il est donc packé avec UPX. Pour unpacker, il suffit de lancer : upx.exe –d crackme.exe.
Et voilà, c’est unpacké …
On passe la fonction « start » pour arriver à la demande de mot de passe (bloc jaune) :


Après le « fgets », on a en vert la partie qui va chiffrer (transformer légèrement) notre mot de passe, ensuite on passe dans la partie orange qui comparera notre mot de passe chiffré avec le chiffré du bon mot de passe. Si c’est bon, on passe dans la partie rouge, sinon bleu.

Dans le premier bloc vert [ebp-1Ch] contient l’index du caractère que l’on est en train de transformer, il est d’ailleurs initialisé à 0 juste après le fgets.
Ensuite on calcul la taille de notre mot de passe situé à ebp-32h. On compare ensuite les 2 pour savoir si on est à la fin ou pas.

Pour la partie transformation (2ème bloc vert), on va chercher le caractère du mot de passe à l’index [ebp-1Ch], on le XOR avec [ebp-1Dh] qui vaut 0x93 (voir un peu plus haut : mov byte ptr [ebp-1Dh], 93h), puis on incrémente l’index.

On a donc un XOR avec 0x93. Pour trouver le bon mot de passe, il suffit de récupérer le chiffré du bon passe et de le XORer avec 0x93.

2.       Résultat
On break sur le strcmp, on note le chiffré du bon mot de passe.
Cela donne : FE FC FD F8 A0 EA.
Après le XOR on obtient le flag : monk3y

Comme « le python c’est bon », voiçi le xor en Python :
"".join([chr(int(v,16)^0x93) for v in ["FE","FC","FD","F8","A0","EA"]])

lundi 26 septembre 2011

CTF Quals CSAW 2011 - Reversing Linux

Salut à tous !

Second writeup du CSAW CTF ! Le reverse Linux à 400 pt.
  1. What ?

    On nous fournit un binaire linux "a.out" que vous pouvez retrouver sur shell-storm ici On go IDA et son pote HexRay.
    On obtient ce code (aprés quelques nettoyages ... ou pas) :

    1. int __cdecl main(int argc, char **argv)
    2. {
    3.   unsigned int v2; // eax@7
    4.   int result; // eax@11
    5.   char v4; // [sp+23h] [bp-4Dh]@3
    6.   char v5; // [sp+24h] [bp-4Ch]@8
    7.   char v6; // [sp+25h] [bp-4Bh]@9
    8.   char v7; // [sp+26h] [bp-4Ah]@9
    9.   char v8; // [sp+27h] [bp-49h]@9
    10.   char v9; // [sp+28h] [bp-48h]@9
    11.   char v10; // [sp+29h] [bp-47h]@9
    12.   char v11; // [sp+2Ah] [bp-46h]@9
    13.   char v12; // [sp+2Bh] [bp-45h]@9
    14.   char v13; // [sp+2Ch] [bp-44h]@9
    15.   char v14; // [sp+2Dh] [bp-43h]@9
    16.   char v15; // [sp+2Eh] [bp-42h]@9
    17.   char v16; // [sp+2Fh] [bp-41h]@9
    18.   char v17; // [sp+30h] [bp-40h]@9
    19.   char v18; // [sp+31h] [bp-3Fh]@9
    20.   char v19; // [sp+32h] [bp-3Eh]@9
    21.   char v20; // [sp+33h] [bp-3Dh]@9
    22.   char v21; // [sp+34h] [bp-3Ch]@9
    23.   char v22; // [sp+35h] [bp-3Bh]@9
    24.   char v23; // [sp+36h] [bp-3Ah]@9
    25.   char v24; // [sp+37h] [bp-39h]@9
    26.   char v25; // [sp+38h] [bp-38h]@9
    27.   char v26; // [sp+39h] [bp-37h]@9
    28.   char v27; // [sp+3Ah] [bp-36h]@9
    29.   char v28; // [sp+3Bh] [bp-35h]@9
    30.   char v29; // [sp+3Ch] [bp-34h]@9
    31.   char v30; // [sp+3Dh] [bp-33h]@9
    32.   char v31; // [sp+3Eh] [bp-32h]@9
    33.   char buffer; // [sp+40h] [bp-30h]@2
    34.   int v33; // [sp+5Ch] [bp-14h]@1
    35.  
    36.   v33 = *MK_FP(__GS__, 20);
    37.   if ( argc <= 1 )
    38.   {
    39.     v4 = 0;
    40.     encode_key(&buffer, &v4);
    41.   }
    42.   else
    43.   {
    44.     encode_key(&buffer, argv[1]);
    45.   }
    46.   if ( argc == 3 )
    47.   {
    48.     strncpy(&buffer, argv[2], 0x1Bu);
    49.     decode_key(&buffer);
    50.   }
    51.   else
    52.   {
    53.     if ( strcmp(argv[3], "I want to speak to a customer service representative.") )
    54.     {
    55.       decode_key(&buffer);
    56.     }
    57.     else
    58.     {
    59.       v2 = 0;
    60.       do
    61.       {
    62.         *(_DWORD *)(&v5 + v2) = 0;
    63.         v2 += 4;
    64.       }
    65.       while ( v2 < 0x1C );
    66.       v5 = 55;
    67.       v6 = 49;
    68.       v7 = 69;
    69.       v8 = 71;
    70.       v9 = -17;
    71.       v10 = -17;
    72.       v11 = 67;
    73.       v12 = -2;
    74.       v13 = 55;
    75.       v14 = 55;
    76.       v15 = 42;
    77.       v16 = 63;
    78.       v17 = 51;
    79.       v18 = 44;
    80.       v19 = -4;
    81.       v20 = 42;
    82.       v21 = 66;
    83.       v22 = 44;
    84.       v23 = 62;
    85.       v24 = 42;
    86.       v25 = -2;
    87.       v26 = 44;
    88.       v27 = -17;
    89.       v28 = 68;
    90.       v29 = -18;
    91.       v30 = -18;
    92.       v31 = 72;
    93.       decode_key(&v5);
    94.     }
    95.   }
    96.   result = 0;
    97.   if ( *MK_FP(__GS__, 20) != v33 )
    98.     __stack_chk_fail();
    99.   return result;
    100. }
    101.  

    Les v4 à v31 sont enf ait les octets d'un buffer. On voit rien de spécial excepté dans le cas ou argc est différent de 3 et que le strcmp ne correspond pas.
    Peut importe comment on y arrive (si on peut y arriver), on voit qu'il set les octets du buffer puis le décode.
    Décodons ce petit buffer !
    On a juste a copier les octets, la fonction de décodage, puis de regarder le résultat :)
    On obtient ce code :

    1. #include <stdio.h>
    2.  
    3. char* data = "\x37\x31\x45\x47\xEF\xEF\x43\xFE\x37\x37\x2A\x3F\x33\x2C\xFC\x2A\x42\x2C\x3E\x2A\xFE\x2C\xEF\x44\xEE\xEE\x48";
    4.  
    5. int main(int argc, char **argv){
    6.     int v1, i;
    7.     for(i=0; i<=26; i++){
    8.         if (i > 6) v1 = -53;
    9.         else v1 = -52;
    10.         printf("%c", (char)(data[i]-v1));
    11.     }
    12.     printf("\n");
    13.     return 0;
    14. }

    On obtient ce résultat : key{##w3ll_tha1_was_3a$y##}