___ ___                                 .__              
     /   |   \   ____ ___  ___         _______|__| ____   ____  
    /    ~    \_/ __ \\  \/  /  ______ \___   /  |/    \_/ __ \ 
    \    Y    /\  ___/ >    <  /_____/  /    /|  |   |  \  ___/ 
     \___|_  /  \___  >__/\_ \         /_____ \__|___|  /\___  >
           \/       \/      \/               \/       \/     \/ 
    
            Berawal dari cuit an di twitter Challange ini dibuat oleh FLARE-ON pada event BLACKHAT USA 2019.

            Seperti biasa challange yang di buat oleh FLAREON selalu berhubungan dengan reversing engineering, 
            dan kita akan disuruh untuk menemukan flag yang valid, dan flag pada challange flareon selalu ber prefix ******@flare-on.com.

            Yuk, kita coba download soal tersebut, dan password untuk membuka file tersebut BHUSA2019 .

            Setelah mendownload dan mengextract file zip tersebut terdapt sebuah file binary MemeCatBattlestation.exe,
            Hal yang pertama kali kita lakukan sebelum melakukan reversing adalah kita harus mengecheck file tersebut 
            bisa mengunaka perintah file

            

            File binary x32 tersebut mengunakan .NET, oleh karena itu ada beberapa options tools yang bisa kita gunakan untuk
            mereverse code binary tersebut menjadi file .NET, kali ini saya menggunakan pendekatan secara dynamic analisis 
            dan tools yang saya gunakan LLSpy.

            Kemudian kita open file MemeCatBattlestation.exe, 
            


            kita bisa lihat terdapat beberapa Class & Form seperti
            1. BattleCatManagerInstance
            2. LogoForm
            3. Program
            4. Stage1Form
            5. Stage2Form
            6. Stage3Form
            7. VictoryForm

            Bisa kita asumsikan pada program tersebut terdapat 3 stage level yakni Stage1Form , Stage3Form & Stage3Form.
            Untuk flag mungkin ada di bagian VictoryForm.

            

Stage1

Pertama kita coba buka aplikasi tersebut dan terdapat sebuah form inputan dan button. Kita disuruh untuk mengiputkan sebuah string pada textbox yang nantinya akan di validasi apakah inputan kita betul atau tidak. Saya coba test input KUCINGLIAR, dan hasilnya adalah Invalid Weapon Code Oleh kerena itu kita coba reverse Stage1Form. ada beberapa fungsi yang perlu kita selidiki yaitu FireButton_Click, fungsi tersebut akan di exekusi setelah user mengclick button Fire! . Bisa kita lihat terdapat validasi inputan user dimana inputan dari textbox harus match dengan string RAINBOW.
                . . . .

                private void FireButton_Click(object sender, EventArgs e){
                    if (this.codeTextBox.Text == "RAINBOW"){
                        this.fireButton.Visible = false;
                        this.codeTextBox.Visible = false;
                        this.armingCodeLabel.Visible = false;
                        this.invalidWeaponLabel.Visible = false;
                        this.WeaponCode = this.codeTextBox.Text;
                        this.victoryAnimationTimer.Start();
                        return;
                    }
                    this.invalidWeaponLabel.Visible = true;
                    this.codeTextBox.Text = "";
                }

                . . . .

                this.fireButton.Click += new EventHandler(this.FireButton_Click);
                
                . . . .
            
Setelah itu kita coba input RAINBOW. Menurut saya Stage1 masih terlihat terlalu mudah untuk di pecahkan.

Stage2

Setelah menginput code yang benar maka, kita akan lanjut ke stage level 2, mari kita check code Stage2Form. Ada beberapa fungsi yang perlu kita check yaitu fungsi isValidWeaponCode, terdapat pengecheckan inputan string dimana inputan string tersebut di XOR dan di set per index nya pada variable expr_19_cp_0 dan nanti nya akan di matching sesuai dengan char[]{ '\u0003','"','"','"','%','\u0014','\u000e','.','?','=',':','9' } bisa kita pastikan bahwa length inputan yang valid adalah 12 byte.
                private bool isValidWeaponCode(string s){
                    char[] array = s.ToCharArray();
                    int length = s.Length;
                    for (int i = 0; i < length; i++){
                        char[] expr_19_cp_0 = array;
                        int expr_19_cp_1 = i;
                        expr_19_cp_0[expr_19_cp_1] ^= (char)(65 + i * 2);
                    }

                    return array.SequenceEqual(new char[]{
                                '\u0003',
                                '"',
                                '"',
                                '"',
                                '%',
                                '\u0014',
                                '\u000e',
                                '.',
                                '?',
                                '=',
                                ':',
                                '9'
                            });
                }
            
untuk memecahkan di stage 2 saya mencoba untuk merecompile ulang dengan pengeditan sedikit code c# nya. dan untuk valid input nya adalah Bagel_Cannon . dan kita coba input dengan valid code tersebut.Dan kita next stage ke level 3 :D untuk full source code nya bisa di check di sini

Stage3

Biasanya semakin naik level nya , tingkat kesulitanya akan semakin tinggi, mari kita check code Stage3Form nya. ada beberapa fungsi yang perlu kita check pada Stage3Form.cs yaitu 1. isValidWeaponCode 2. getCatGenetics 3. InitializeBattleCat Pada fungsi isValidWeaponCode(), inputan user di tampung dalam variable s . Setelah itu memangil fungsi getCatGenetics(), fungsi tersebut melakukan encoding berupa base64 dengan value yang di ambil dari variable this.PriorWeaponCode. Variable PriorWeaponCode merupakan inputan user pada stage level 2 yaitu Bagel_Cannon dan nantinya akan di set ke variable catGenetics. Terakhir adalah memanggil InitializeBattleCat(Encoding.UTF8.GetBytes(catGenetics), Encoding.UTF8.GetBytes(s)) dan di bandingankan dengan nilai byte[]{ 95,193,50,12,127,228,98,6,215,46,200,106,251,121,186,119,109,73,35,14,20 } bisa kita pastikan bahwa length inputan yang valid adalah 21 byte.
                private bool isValidWeaponCode(string s){
                    string catGenetics = this.getCatGenetics();
                    return BattleCatManagerInstance.InitializeBattleCat(Encoding.UTF8.GetBytes(catGenetics), 
                    Encoding.UTF8.GetBytes(s)).SequenceEqual(new byte[]{
                        95,
                        193,
                        50,
                        12,
                        127,
                        228,
                        98,
                        6,
                        215,
                        46,
                        200,
                        106,
                        251,
                        121,
                        186,
                        119,
                        109,
                        73,
                        35,
                        14,
                        20
                    });
                }
            
untuk memecahkan di stage 3 saya mencoba untuk merecompile ulang dengan pengeditan sedikit code c# nya. Dan valid code nya adalah Defeat_them_with_love, dan setelah menginput code tersebut kita otomatis di direct ke page VictoryForm dan langsung mendapatkan flag nya yaitu Kitteh_save_galixy@flare-on.com . untuk full source code nya bisa di check di sini. yang menarik dari soal ini adalah user tidak memungkinkan untuk mempatch langsung si binary nya ke VictoryForm.cs karena bisa kita check, bahwa flag nya akan di generate berdasarkan code yang valid dari stage 3.
                private void VictoryForm_Load(object sender, EventArgs e){
                byte[] data = new byte[] { 74, 240, 181, 167, 229, 232, 186, 112, 186,
                                234, 154, 75, 116, 154, 71, 235, 31, 132, 41, 179, 119,
                                137, 199, 167, 215, 148, 25, 196, 152, 253, 227
                            };
                    byte[] bytes = BattleCatManagerInstance.InitializeBattleCat(Encoding.UTF8.GetBytes(this.Arsenal), data);
                    this.flagLabel.Text = Encoding.UTF8.GetString(bytes);
                }
            
Sekain dan terimakasih karena meluangkan waktu untuk membaca artikel ini :)