___ ___                                 .__              
     /   |   \   ____ ___  ___         _______|__| ____   ____  
    /    ~    \_/ __ \\  \/  /  ______ \___   /  |/    \_/ __ \ 
    \    Y    /\  ___/ >    <  /_____/  /    /|  |   |  \  ___/ 
     \___|_  /  \___  >__/\_ \         /_____ \__|___|  /\___  >
           \/       \/      \/               \/       \/     \/ 
    
            Pada chall infernoctf2019 ini, saya mencoba untuk menyelesaikan challange Web Crackme dengan point 399.
            kita buka ke halaman web nya 

            


            kita bisa lihat terdapat beberapa script yang di load namun kita fokus ke 3 file 
            1. app.js
            2. assembly.wat
            3. script.js

            

App.js

kita coba lihat beberapa potongan dari app.js, terdapat methods dan memanggil sebuah fungsi selectExample & execute
                . . . .

                methods: {
                    async selectExample(example) {
                        window.location.hash = example;
                        this.selectedExample = example;

                        const [wat, js] = await Promise.all([
                            loadText(example + '/assembly.wat'),
                            loadText(example + '/script.js'),
                        ]);

                        this.wat = wat;
                        this.watHighlighted = hljs.highlight('clojure', wat).value;
                        this.js = js;
                        this.jsHighlighted = hljs.highlight('js', js).value;

                        return 0;
                    },
                    async execute() {

                        var key = document.getElementById('key').value;
                        var stringFromKey = "";
                        for (var i = 0; i < key.length; i++) {
                            stringFromKey+=key.charCodeAt(i).toString(16);
                        }
                        const parsedWat = wabtCompiler.parseWat("", this.wat);
                        const buffer = parsedWat.toBinary({}).buffer;
                        const wasmModule = await WebAssembly.compile(buffer);

                        eval(this.js);

                        return 0;
                    }
                }

            
mari kita pecah per statement pada fungsi selectExample , bisa kita lihat code tersebut melakukan request http untuk meload sebuah script assembly.wat dan script.js kemudian akan di set ke variable wat & js kemudian di tampung kedalam set kedalam this.wat & this.js

                        const [wat, js] = await Promise.all([
                            loadText(example + '/assembly.wat'),
                            loadText(example + '/script.js'),
                        ]);

                        this.wat = wat;
                        this.watHighlighted = hljs.highlight('clojure', wat).value;
                        this.js = js;
                        this.jsHighlighted = hljs.highlight('js', js).value;
            
kemudian fungsi execute di jalankan, semua inputan user pada textbox akan di set kedalam variable key kemudian di convert kedalam hex. dan nanti akan di bandingkan value nya dengan nilai hex yang ada di dalam code assembly.wat

                        var key = document.getElementById('key').value;
                        var stringFromKey = "";
                        for (var i = 0; i < key.length; i++) {
                            stringFromKey+=key.charCodeAt(i).toString(16);
                        }
                        const parsedWat = wabtCompiler.parseWat("", this.wat);
                        const buffer = parsedWat.toBinary({}).buffer;
                        const wasmModule = await WebAssembly.compile(buffer);

                        eval(this.js);
            

assembly.wat

berikut ini adalah kode yang assembly yang di load tadi, terdapat 2 buah fungsi myFunction1 & myFunction2
                (module
                  (memory 1)
                  (func $myFunction1 (result i32)
                   (i32.store
                      (i32.const 0)
                      (i32.const 0xd359beef) 
                    )

                    (i32.store
                      (i32.const 3)
                      (i32.const 0x5579)
                    )
                    
                    (i32.store
                        (i32.const 5)
                        (i32.const 0x66)
                    )
                    (i32.load
                      (i32.const 2)
                    )
                  )

                  (func $myFunction2 (result i32)
                    (i32.store
                      (i32.const 0)
                      (i32.const 0xc939ba2d)
                    )
                   (i32.store
                      (i32.const 3)
                      (i32.const 0x7165) 
                    )
                    (i32.store16
                        (i32.const 4)
                        (i32.const 0x2D4D) 
                    )
                    (i32.load
                      (i32.const 2)
                    )
                  )
                  (export "myFunction1" (func $myFunction1))
                  (export "myFunction2" (func $myFunction2))
                )
            
pada fungsi myFunction1,
                (module
                  (memory 1)
                  (func $myFunction1 (result i32)
                   (i32.store
                      (i32.const 0)
                      (i32.const 0xd359beef) 
                    )

                    (i32.store
                      (i32.const 3)
                      (i32.const 0x5579)
                    )
                    
                    (i32.store
                        (i32.const 5)
                        (i32.const 0x66)
                    )
                    (i32.load
                      (i32.const 2)
                    )
                  )
            
pada bagian i32.store -> i32.const 0 value tersebut di isi 0xd359beef ketika di load maka yang akan terjadi akan di reverse menjadi 0xefbe59d3
0 1 2 3
ef be 59 d3
pada bagain i32.store -> i32.const 3 value isi0x5579 maka yang akan terjadi akan di reverse menjadi 0x7955 dan pada index ke 3 maka akan di replace dengan nilai baru
0 1 2 3 4
ef be 59 79 55
dan pada bagian i32.store -> i32.const 5 value tersebut di isi0x66 maka pada index ke 5 di isi dengan value 66
0 1 2 3 4 5
ef be 59 79 55 66
maka fungsi myFunction1 memiliki nilai 0xefbe59795566 kemudian pada bagian i32.load -> (i32.const 2) maka yang terjadi adalah di mengambil 0x59795566 kemudian di reverse 0x66557959 dan ini berlaku untuk fungsi myFunction2 memiliki nilai 0x2d4d6539

script.js

pada bagian ini bisa kita lihat fungsi pada wasm tadi di load kemudian setiap fungsi akan di set kesebuah variable res1 & res2 dan di gabung menjadi 1 variable yaitu finalres
                const wasmInstance = new WebAssembly.Instance(wasmModule, {});
                const { myFunction1,myFunction2 } = wasmInstance.exports;

                let res1 = myFunction1().toString(16);
                let res2 = myFunction2().toString(16);

                let finalres = res1 + res2;

                if (finalres ==  stringFromKey){
                    alert("Here you go infernoCTF{"+key+"}");
                }
                else{
                    alert("Naah, Remember I'm the future!!");
                }
            
untuk membuktikan nya kita coba load module tadi via console kita coba ambil variable finalres, nilai nya sama 665579592d4d6539 kemudian langkah terakhir adalah kita mencoba untuk mendecode nilai hex tersebut, saya membuat sebuah snipet code seperti ini
                let key = "";
                for (var i = 0; i < finalres.length; i++) {
                    key += (i % 2 === 0) ? String.fromCharCode(parseInt(finalres.substr(i, 2), 16)) : '';
                }
            
kemudian kita coba run code tersebut dan kita coba input flag tersebut infernoCTF{fUyY-Me9} Sekain dan terimakasih karena meluangkan waktu untuk membaca artikel ini :)