====== DotNet ====== ===== Enoncé ===== Un fichier nous est proposé : DotNetReversing.exe ===== Solution ===== Comme le titre de l'épreuve et le nom du fichier l'indiquent, il s'agit d'une application DotNet. Voyons d'abord ce que l'ont peut apprendre lors de son execution : {{:csaw2013_quals:reversing:dotnet.png|}} Il s'agit de trouver le mot de passe qui nous donnera le flag. On peut voir que le programme n'aime pas trop qu'on lui envoie une chaine de caractère, essayons avec un entier. {{:csaw2013_quals:reversing:dotnet2.png|}} C'est mieux. Le but est donc de trouver un entier. Quand il s'agit de DotNet, on pense tout de suite à Reflector (ou à tout équivalent OpenSource) pour décompiler le binaire. On passe donc notre executable à la moulinette : Notre exe contient 1 classe et 3 fonctions : private static void Main(string[] args) private static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) private static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) Les fonctions de chiffrage et déchiffrage permettent d'afficher le flag une fois le mot de passe découvert. Regardons le contenu du Main : private static void Main(string[] args) { Console.WriteLine("Greetings challenger! Step right up and try your shot at gaining the flag!"); Console.WriteLine("You'll have to know the pascode to unlock the prize:"); string value = Console.ReadLine(); long num = Convert.ToInt64(value); long num2 = 53129566096L; long num3 = 65535655351L; if ((num ^ num2) == num3) { Console.WriteLine("yay"); } else { Console.WriteLine("Incorrect, try again!"); } try { byte[] iV = new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; byte[] array = new byte[16]; BitConverter.GetBytes(num).CopyTo(array, 0); BitConverter.GetBytes(num).CopyTo(array, 8); string s = "ls/5RTxwflDrqr5G8pO9cQ1NlgQcFjcJj9x4z7oIhlfY4w42GAFqKbyzwqHAZQBZa5ctysKKWIbTgU2VxoRYohxCbPyV6sEU/tn+sIxNg6A/r5OJnIMqTs0seMrzWh5J"; Thread.Sleep(500); Console.WriteLine(aClass.DecryptStringFromBytes_Aes(Convert.FromBase64String(s), array, iV)); Console.WriteLine("Success!!"); } catch (Exception arg) { Console.WriteLine("ERROR!!! darn. huh? how did I get here? Hmm, something must have gone wrong. What am I doing?", arg); } Console.WriteLine("press key to continue"); Console.ReadKey(); } On remarque rapidement le IF qui nous envoie soit dans la routine d'affichage du flag, soit celle d'affichage du message "Incorrect, try again!" : if ((num ^ num2) == num3) Avec num=valeure entière saisie par l'utilisateur, num2=53129566096 et num3=65535655351 Il faut donc que la valeur saisie par l'utilisateur "XOR" 53129566096 soit égale à 65535655351. Celà revient à dire que la valeur recherchée est égale à 53129566096 XOR 65535655351 Même calc.exe peut résoudre ça pour nous, la valeure recherchée est 13371337255 Testons {{:csaw2013_quals:reversing:dotnet3.png|}} Bingo !