[CodeEngn Basic 13] Find the Answer feat. C#

2017. 8. 20. 10:310x02 Reverse Engineer/0x01. CodeEngn

728x90

문제 : Find the Answer 


바이너리 실행 :

 

 [그림 1] 비밀번호를 입력하는 프로그램 


틀리면 계속 반복하는 프로그램 (부르트포싱이 가능한가?)

 

 [그림 2] 틀린 비밀번호 



바이너리를 뜯어보아요.


C# 프로그램이다..!! C#은 디컴파일러가 따로 존재한다.


[STAThread]

private static void Main(string[] args)

{

    string plainText = "";

    string cipherText = "BnCxGiN4aJDE+qUe2yIm8Q==";

    string passPhrase = "^F79ejk56$\x00a3";

    string saltValue = "DHj47&*)$h";

    string hashAlgorithm = "MD5";

    int passwordIterations = 0x400;

    string initVector = "&!\x00a3$%^&*()CvHgE!";

    int keySize = 0x100;


    RijndaelSimple.Encrypt(plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);


    plainText = RijndaelSimple.Decrypt(cipherText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);


Label_0056:


    Console.WriteLine("Please enter the password: ");

    if (Console.ReadLine() == plainText)

    {

        Console.WriteLine("Well Done! You cracked it!");

        Console.ReadLine();

    }

    else

    {

        Console.WriteLine("Bad Luck! Try again!");

        goto Label_0056;

    }

}


 


 

 


public static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)

{

    byte[] bytes = Encoding.ASCII.GetBytes(initVector);

    byte[] rgbSalt = Encoding.ASCII.GetBytes(saltValue);

    byte[] buffer = Encoding.UTF8.GetBytes(plainText);

    byte[] rgbKey = new PasswordDeriveBytes(passPhrase, rgbSalt, hashAlgorithm, passwordIterations).GetBytes(keySize / 8);

    RijndaelManaged managed = new RijndaelManaged();

    managed.Mode = CipherMode.CBC;

    ICryptoTransform transform = managed.CreateEncryptor(rgbKey, bytes);

    MemoryStream stream = new MemoryStream();

    CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);

    stream2.Write(buffer, 0, buffer.Length);

    stream2.FlushFinalBlock();

    byte[] inArray = stream.ToArray();

    stream.Close();

    stream2.Close();

    return Convert.ToBase64String(inArray);

}


 


 

 


public static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)

{

    byte[] bytes = Encoding.ASCII.GetBytes(initVector);

    byte[] rgbSalt = Encoding.ASCII.GetBytes(saltValue);

    byte[] buffer = Convert.FromBase64String(cipherText);

    byte[] rgbKey = new PasswordDeriveBytes(passPhrase, rgbSalt, hashAlgorithm, passwordIterations).GetBytes(keySize / 8);

    RijndaelManaged managed = new RijndaelManaged();

    managed.Mode = CipherMode.CBC;

    ICryptoTransform transform = managed.CreateDecryptor(rgbKey, bytes);

    MemoryStream stream = new MemoryStream(buffer);

    CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);

    byte[] buffer5 = new byte[buffer.Length];

    int count = stream2.Read(buffer5, 0, buffer5.Length);

    stream.Close();

    stream2.Close();

    return Encoding.UTF8.GetString(buffer5, 0, count);

}


 


 



우선, 디컴파일 된 코드를 다 올려보았다. 

코드가 노출 되었다는 의미는 맘대로 수정도 가능하다는 이야기. 


using System;


public class RijndaelSimpleTest

{

    [STAThread]

    private static void Main(string[] args)

    {

        string plainText = "";

        string cipherText = "BnCxGiN4aJDE+qUe2yIm8Q==";

        string passPhrase = "^F79ejk56$\x00a3";

        string saltValue = "DHj47&*)$h";

        string hashAlgorithm = "MD5";

        int passwordIterations = 0x400;

        string initVector = "&!\x00a3$%^&*()CvHgE!";

        int keySize = 0x100;

        RijndaelSimple.Encrypt(plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);

        plainText = RijndaelSimple.Decrypt(cipherText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);

    Label_0056:

        Console.WriteLine("Please enter the password: ");

        if (Console.ReadLine() != plainText)

        {

            Console.WriteLine("Well Done! You cracked it!");

            Console.WriteLine("Real Flag = " + plainText);

            Console.ReadLine();

        }

        else

        {

            Console.WriteLine("Bad Luck! Try again!");

            goto Label_0056;

        }

    }

}


 


루틴만 안복잡하면 c#은 쉽다.


 

 [그림 3] Success ~