Kaspersky Industrial CTF Quals 2017 - rev700 - Web Keygen Writeup

Hi,

Typically this was not really a web task but a reversing one instead. The task implements a relatively small and straightforward custom VM interpreter using Javascript.

crackme! http://95.85.55.168/vmctf.html

Here is my solver in case you want to skip the explanation:
https://pastebin.com/2qKjQ7wy

Obviously, we need to reverse the VM implementation before we can start reversing the VM bytecode.

A top-down look at the obfuscated source code shows that CoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCoCo function fetch an opcode and dispatches the opcode to the corresponding operation.

Following is the list of the opcode with corresponding x86 operation.

1 - PUSH
2 -  MOV
3 - SUB
4 - CALL
5 - ADD
6 - CMP
7 - JNZ
8 - JMP
9 - JNO
10 - MOVU
11 - XOR
12 - DIV/MOD
13 - OR
14 - POP
15 - RET
16 - JZ
17 - AND
18 - SHR

To get an execution trace, we modify the code and add some logging messages to all operations.

Let's take the XOR operation as example.

    nextInst()
    {
        var opcode = this.fetch();
        switch(opcode)
        {
            case 11:
                var r1 = this.REGSZ();
                var r2 = this.REGSZ();                
                var p = r1.LOAD();
  var q = r2.LOAD();
                var acc = p ^ q;    
  console.log("XOR "+p+", "+q);
                r1.STORE(acc);             
                break;
 
        }
    }



It is enough to add logging messages to all operations and execute the script to get a readable trace and understand what the program does.

Here is the de-obfuscated version of the VM implementation


class Reg0
{
    constructor(vm)
    {
        this.stack = vm.stack;
        this.v3 = vm.fetch1();        
        this.utype = vm.fetch1();        
        this.v5 = vm.fetch1();
    }
    
    
    
    LOAD()
    {
        switch( this.utype )
        {
            case 1:
                return this.stack.getUint8(this.v3)*this.v5;
            case 2:
                return this.stack.getUint16(this.v3)*this.v5;
            case 4:
                return this.stack.getUint32(this.v3)*this.v5;
        }     
    }
    
    STORE(arg)
    {        
        switch( this.utype )
        {
            case 1:
               this.stack.setUint8(this.v3,arg);
               break;
            case 2:
               this.stack.setUint16(this.v3,arg);
               break;
            case 4:
               this.stack.setUint32(this.v3,arg);
               break;
        }
        this.v5 = 1;
    }    
}

class Reg1
{
    constructor(vm)
    {
        this.arg = vm.fetch4();
    }
    

    LOAD()
    {
        return this.arg;       
    }
    
    STORE(arg)
    {
    }
}

class Reg
{
    constructor(vm)
    {      
        this.v3 = 0;
        
        var arg = vm.fetch1(); 
        
        while( arg-- )
        {
            this.v3 += vm.fetch().LOAD();            
        }
        
        this.v3 &= 0xFFFFFFFF;
        
        this.val = vm.val;
        this.stack = vm.stack;
    }
}

class Reg8 extends Reg
{


    LOAD()
    {          
        return this.val.getUint8(this.v3);
    }
    
    STORE(arg)
    {
        this.val.setUint8(this.v3,arg);
    }        
}

class Reg32 extends Reg
{



    LOAD()
    {          
        return this.val.getUint32(this.v3);
    }
    
    STORE(arg)
    {
        this.val.setUint32(this.v3,arg);
    }        
}

class VM
{
    constructor(mem)
    {
        this.val = new DataView(mem.buffer);
        this.IP = 0;
        this.stack = new DataView(new ArrayBuffer(32));
        var loc = mem.length;
        this.stack.setInt32(16,loc);
        
        this.ZF = false;
        this.OF = false;        
    }
    
    
    fetch4()
    {
        var arg = this.val.getUint32(this.IP);
        this.IP += 4;
        return arg;        
    }
    
    fetch1()
    {
        var arg = this.val.getUint8(this.IP);
        this.IP++;
        return arg;
    }
    
    fetch()
    {
        var arg = this.fetch1();
        switch(arg )
        {
            case 1:
                return new Reg0(this);                
            case 2:
                return new Reg1(this);
            case 3:
                return new Reg8(this);
            case 4:
                return new Reg32(this);
        }
        return null;
    }
    
    
    push(arg)
    {
        var loc = this.stack.getInt32(16) - 4;        
        this.stack.setInt32(16,loc);
        this.val.setUint32(loc,arg)
        return loc;
    }
    
    pop()
    {
        var loc = this.stack.getInt32(16);
        var arg = this.val.getUint32(loc);
        loc += 4;
        this.stack.setInt32(16,loc);        
        return arg;
    }


    nextInst()
    {
        var opcode = this.fetch1();
        switch(opcode)
        {
            case 4:
                var r1 = this.fetch();                
                var acc = r1.LOAD();
                console.log("call, "+acc);
                this.push(this.IP);
                this.IP = acc;    
                break;
            case 2:
                var r1 = this.fetch();
                var r2 = this.fetch();                
                
    var p = r2.LOAD();   
    console.log("mov r1, "+p);
                r1.STORE(p);
                break;
            case 8:
                var r1 = this.fetch();                
                
                this.IP = r1.LOAD();
    console.log("jmp, "+this.IP);
                break;
            case 10:            
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var q = r2.LOAD();
                r1.STORE(q>>>0);
    
    console.log("movu r1, "+ q);
                                
                break;
            case 5:
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var p = r1.LOAD();
    var q = r2.LOAD();
                var acc = p + q;
    
    console.log("add "+p+", "+q);
                                
                this.OF = new Boolean(acc>>32);

                r1.STORE(acc);
                break;
            case 18:
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var p = r1.LOAD();
    var q = r2.LOAD();
                var acc = p >>> q;
    
    console.log("rsh "+p+", "+q)
    
                r1.STORE(acc);     
                break;
            case 11:
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var p = r1.LOAD();
    var q = r2.LOAD();
                var acc = p ^ q;
    
    console.log("xor "+p+", "+q);
                r1.STORE(acc);             
                break;
            case 3:        
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var p = r1.LOAD();
    var q = r2.LOAD();
                var acc = p + ((~q) + 1);
    
    console.log("sub "+p+", "+q);
                this.OF = new Boolean(acc>>32);
                    
                r1.STORE(acc);
                break;
            case 15:
                var r1 = this.fetch();
                var acc = this.pop();                
                this.IP = acc;
    console.log("ret");
                break;
            case 14:
                var r1 = this.fetch();
                console.log("pop");
                var acc = this.pop();                                
                r1.STORE(acc);
                break;
            case 17:
                var r1 = this.fetch();
                var r2 = this.fetch();
                var p = r1.LOAD();
    var q = r2.LOAD();
    
                var acc = p & q; 

                console.log("and "+p+", "+q);    
                r1.STORE(acc);
                break;
            case 9:        
                var r1 = this.fetch();                     
                if(this.OF == false)                
                {
                    this.IP = r1.LOAD();    
                }                
                break;
            case 1:
                var r1 = this.fetch();                
                var p = r1.LOAD();
                this.push(p);
    console.log("push "+p);
                break;
            case 6:
                var r1 = this.fetch();
                var r2 = this.fetch();                
                var p = r1.LOAD();
    var q = r2.LOAD()
                this.ZF = ( p == q);
    
    console.log("cmp "+p+", "+q);
                
                var acc = r1.LOAD() + ((~r2.LOAD()) + 1);
                this.OF = new Boolean(acc>>32);
                break;
            case 7:                                
                var r1 = this.fetch();  
                
    console.log("jz "+this.IP);
    
                if(this.ZF == false)                
                {
                    this.IP = r1.LOAD();    
                }
    else
     console.log("[+] Correct Password");
                break;
            case 13:
                var r1 = this.fetch();
                var r2 = this.fetch();
                var p = r1.LOAD();
    var q = r2.LOAD()
                var acc = p | q;  
                console.log("or "+p+", "+q);    
                r1.STORE(acc);
                break;
            case 16:                
                var r1 = this.fetch();                
                if(this.ZF == true)          
                {
                    this.IP = r1.LOAD();         
     console.log("jnz "+this.IP);     
                }            
                break;
            case 12:
                var r1 = this.fetch();
                   
                var arg = (this.stack.getInt32(8) << 32) | this.stack.getInt32(0);
    var p = r1.LOAD();
                var loc = arg / p;
    
    console.log("div "+arg+", "+p); 
    
                this.stack.setInt32(0,loc);
    var p = r1.LOAD();
                var loc = arg % p;
    console.log("mod "+arg+", "+p); 
                this.stack.setInt32(8,loc);                
                break;
        }
    }
}

function GetFlag(input)
{
    var mem = new Uint8Array([1,1,20,4,1,2,1,20,4,1,1,16,4,1,3,1,16,4,1,2,0,0,0,44,1,1,24,4,1,2,3,2,2,255,255,255,212,1,20,4,1,2,0,0,0,115,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,1,2,0,0,0,20,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,2,2,0,0,0,32,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,3,2,0,0,0,23,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,4,2,0,0,0,2,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,5,2,0,0,0,98,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,6,2,0,0,0,42,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,7,2,0,0,0,119,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,8,2,0,0,0,121,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,9,2,0,0,0,29,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,10,2,0,0,0,33,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,11,2,0,0,0,113,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,12,2,0,0,0,112,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,13,2,0,0,0,103,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,14,2,0,0,0,94,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,15,2,0,0,0,6,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,16,2,0,0,0,0,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,17,2,0,0,0,30,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,18,2,0,0,0,91,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,19,2,0,0,0,113,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,20,2,0,0,0,125,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,21,2,0,0,0,103,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,22,2,0,0,0,95,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,23,2,0,0,0,113,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,24,2,0,0,0,123,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,25,2,0,0,0,111,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,26,2,0,0,0,80,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,27,2,0,0,0,2,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,28,2,0,0,0,119,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,29,2,0,0,0,103,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,30,2,0,0,0,90,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,31,2,0,0,0,115,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,32,2,0,0,0,9,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,33,2,0,0,0,25,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,34,2,0,0,0,39,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,35,2,0,0,0,1,2,3,3,2,255,255,255,212,1,20,4,1,2,0,0,0,36,2,0,0,0,5,1,2,0,0,0,8,2,1,0,4,1,4,2,2,0,0,0,8,1,20,4,1,1,1,0,4,1,1,2,18,52,86,120,4,2,0,0,4,199,5,1,16,4,1,2,0,0,0,12,6,1,0,4,1,2,51,229,174,64,7,2,0,0,4,164,2,4,2,2,255,255,255,252,1,20,4,1,2,0,0,0,0,2,4,2,2,255,255,255,252,1,20,4,1,2,0,0,0,0,8,2,0,0,3,217,2,1,4,4,1,4,2,2,255,255,255,252,1,20,4,1,5,1,4,4,1,2,0,0,0,1,2,4,2,2,255,255,255,252,1,20,4,1,1,4,4,1,6,4,2,2,255,255,255,252,1,20,4,1,2,0,0,0,37,9,2,0,0,4,149,2,1,8,4,1,4,2,2,255,255,255,252,1,20,4,1,10,1,4,4,1,3,3,2,255,255,255,212,1,20,4,1,1,8,4,1,2,1,0,4,1,4,2,2,255,255,255,252,1,20,4,1,11,1,8,4,1,1,8,4,1,2,1,24,4,1,2,0,0,0,8,12,1,24,4,1,2,1,0,4,1,4,2,2,0,0,0,8,1,20,4,1,10,1,8,4,1,3,2,1,0,4,1,1,8,4,1,11,1,4,4,1,1,8,4,1,2,1,0,4,1,4,2,2,0,0,0,12,1,20,4,1,5,1,0,4,1,4,2,2,255,255,255,252,1,20,4,1,2,3,1,1,0,4,1,1,7,1,1,8,2,0,0,3,175,11,1,0,4,1,1,0,4,1,8,2,0,0,4,174,13,1,0,4,1,2,255,255,255,255,14,1,24,4,1,2,1,16,4,1,1,20,4,1,14,1,20,4,1,15,2,0,0,0,0,1,1,20,4,1,2,1,20,4,1,1,16,4,1,3,1,16,4,1,2,0,0,4,8,2,4,2,2,255,255,251,248,1,20,4,1,2,0,0,0,0,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,4,2,119,7,48,150,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,8,2,238,14,97,44,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,12,2,153,9,81,186,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,16,2,7,109,196,25,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,20,2,112,106,244,143,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,24,2,233,99,165,53,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,28,2,158,100,149,163,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,32,2,14,219,136,50,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,36,2,121,220,184,164,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,40,2,224,213,233,30,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,44,2,151,210,217,136,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,48,2,9,182,76,43,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,52,2,126,177,124,189,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,56,2,231,184,45,7,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,60,2,144,191,29,145,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,64,2,29,183,16,100,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,68,2,106,176,32,242,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,72,2,243,185,113,72,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,76,2,132,190,65,222,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,80,2,26,218,212,125,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,84,2,109,221,228,235,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,88,2,244,212,181,81,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,92,2,131,211,133,199,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,96,2,19,108,152,86,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,100,2,100,107,168,192,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,104,2,253,98,249,122,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,108,2,138,101,201,236,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,112,2,20,1,92,79,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,116,2,99,6,108,217,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,120,2,250,15,61,99,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,124,2,141,8,13,245,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,128,2,59,110,32,200,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,132,2,76,105,16,94,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,136,2,213,96,65,228,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,140,2,162,103,113,114,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,144,2,60,3,228,209,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,148,2,75,4,212,71,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,152,2,210,13,133,253,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,156,2,165,10,181,107,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,160,2,53,181,168,250,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,164,2,66,178,152,108,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,168,2,219,187,201,214,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,172,2,172,188,249,64,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,176,2,50,216,108,227,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,180,2,69,223,92,117,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,184,2,220,214,13,207,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,188,2,171,209,61,89,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,192,2,38,217,48,172,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,196,2,81,222,0,58,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,200,2,200,215,81,128,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,204,2,191,208,97,22,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,208,2,33,180,244,181,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,212,2,86,179,196,35,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,216,2,207,186,149,153,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,220,2,184,189,165,15,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,224,2,40,2,184,158,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,228,2,95,5,136,8,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,232,2,198,12,217,178,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,236,2,177,11,233,36,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,240,2,47,111,124,135,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,244,2,88,104,76,17,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,248,2,193,97,29,171,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,0,252,2,182,102,45,61,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,0,2,118,220,65,144,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,4,2,1,219,113,6,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,8,2,152,210,32,188,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,12,2,239,213,16,42,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,16,2,113,177,133,137,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,20,2,6,182,181,31,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,24,2,159,191,228,165,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,28,2,232,184,212,51,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,32,2,120,7,201,162,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,36,2,15,0,249,52,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,40,2,150,9,168,142,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,44,2,225,14,152,24,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,48,2,127,106,13,187,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,52,2,8,109,61,45,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,56,2,145,100,108,151,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,60,2,230,99,92,1,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,64,2,107,107,81,244,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,68,2,28,108,97,98,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,72,2,133,101,48,216,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,76,2,242,98,0,78,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,80,2,108,6,149,237,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,84,2,27,1,165,123,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,88,2,130,8,244,193,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,92,2,245,15,196,87,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,96,2,101,176,217,198,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,100,2,18,183,233,80,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,104,2,139,190,184,234,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,108,2,252,185,136,124,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,112,2,98,221,29,223,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,116,2,21,218,45,73,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,120,2,140,211,124,243,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,124,2,251,212,76,101,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,128,2,77,178,97,88,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,132,2,58,181,81,206,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,136,2,163,188,0,116,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,140,2,212,187,48,226,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,144,2,74,223,165,65,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,148,2,61,216,149,215,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,152,2,164,209,196,109,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,156,2,211,214,244,251,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,160,2,67,105,233,106,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,164,2,52,110,217,252,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,168,2,173,103,136,70,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,172,2,218,96,184,208,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,176,2,68,4,45,115,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,180,2,51,3,29,229,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,184,2,170,10,76,95,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,188,2,221,13,124,201,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,192,2,80,5,113,60,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,196,2,39,2,65,170,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,200,2,190,11,16,16,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,204,2,201,12,32,134,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,208,2,87,104,181,37,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,212,2,32,111,133,179,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,216,2,185,102,212,9,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,220,2,206,97,228,159,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,224,2,94,222,249,14,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,228,2,41,217,201,152,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,232,2,176,208,152,34,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,236,2,199,215,168,180,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,240,2,89,179,61,23,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,244,2,46,180,13,129,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,248,2,183,189,92,59,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,1,252,2,192,186,108,173,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,0,2,237,184,131,32,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,4,2,154,191,179,182,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,8,2,3,182,226,12,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,12,2,116,177,210,154,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,16,2,234,213,71,57,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,20,2,157,210,119,175,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,24,2,4,219,38,21,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,28,2,115,220,22,131,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,32,2,227,99,11,18,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,36,2,148,100,59,132,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,40,2,13,109,106,62,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,44,2,122,106,90,168,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,48,2,228,14,207,11,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,52,2,147,9,255,157,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,56,2,10,0,174,39,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,60,2,125,7,158,177,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,64,2,240,15,147,68,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,68,2,135,8,163,210,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,72,2,30,1,242,104,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,76,2,105,6,194,254,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,80,2,247,98,87,93,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,84,2,128,101,103,203,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,88,2,25,108,54,113,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,92,2,110,107,6,231,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,96,2,254,212,27,118,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,100,2,137,211,43,224,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,104,2,16,218,122,90,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,108,2,103,221,74,204,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,112,2,249,185,223,111,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,116,2,142,190,239,249,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,120,2,23,183,190,67,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,124,2,96,176,142,213,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,128,2,214,214,163,232,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,132,2,161,209,147,126,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,136,2,56,216,194,196,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,140,2,79,223,242,82,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,144,2,209,187,103,241,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,148,2,166,188,87,103,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,152,2,63,181,6,221,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,156,2,72,178,54,75,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,160,2,216,13,43,218,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,164,2,175,10,27,76,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,168,2,54,3,74,246,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,172,2,65,4,122,96,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,176,2,223,96,239,195,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,180,2,168,103,223,85,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,184,2,49,110,142,239,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,188,2,70,105,190,121,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,192,2,203,97,179,140,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,196,2,188,102,131,26,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,200,2,37,111,210,160,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,204,2,82,104,226,54,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,208,2,204,12,119,149,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,212,2,187,11,71,3,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,216,2,34,2,22,185,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,220,2,85,5,38,47,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,224,2,197,186,59,190,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,228,2,178,189,11,40,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,232,2,43,180,90,146,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,236,2,92,179,106,4,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,240,2,194,215,255,167,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,244,2,181,208,207,49,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,248,2,44,217,158,139,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,2,252,2,91,222,174,29,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,0,2,155,100,194,176,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,4,2,236,99,242,38,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,8,2,117,106,163,156,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,12,2,2,109,147,10,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,16,2,156,9,6,169,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,20,2,235,14,54,63,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,24,2,114,7,103,133,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,28,2,5,0,87,19,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,32,2,149,191,74,130,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,36,2,226,184,122,20,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,40,2,123,177,43,174,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,44,2,12,182,27,56,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,48,2,146,210,142,155,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,52,2,229,213,190,13,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,56,2,124,220,239,183,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,60,2,11,219,223,33,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,64,2,134,211,210,212,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,68,2,241,212,226,66,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,72,2,104,221,179,248,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,76,2,31,218,131,110,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,80,2,129,190,22,205,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,84,2,246,185,38,91,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,88,2,111,176,119,225,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,92,2,24,183,71,119,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,96,2,136,8,90,230,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,100,2,255,15,106,112,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,104,2,102,6,59,202,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,108,2,17,1,11,92,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,112,2,143,101,158,255,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,116,2,248,98,174,105,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,120,2,97,107,255,211,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,124,2,22,108,207,69,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,128,2,160,10,226,120,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,132,2,215,13,210,238,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,136,2,78,4,131,84,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,140,2,57,3,179,194,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,144,2,167,103,38,97,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,148,2,208,96,22,247,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,152,2,73,105,71,77,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,156,2,62,110,119,219,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,160,2,174,209,106,74,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,164,2,217,214,90,220,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,168,2,64,223,11,102,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,172,2,55,216,59,240,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,176,2,169,188,174,83,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,180,2,222,187,158,197,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,184,2,71,178,207,127,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,188,2,48,181,255,233,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,192,2,189,189,242,28,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,196,2,202,186,194,138,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,200,2,83,179,147,48,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,204,2,36,180,163,166,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,208,2,186,208,54,5,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,212,2,205,215,6,147,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,216,2,84,222,87,41,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,220,2,35,217,103,191,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,224,2,179,102,122,46,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,228,2,196,97,74,184,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,232,2,93,104,27,2,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,236,2,42,111,43,148,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,240,2,180,11,190,55,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,244,2,195,12,142,161,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,248,2,90,5,223,27,2,4,3,2,255,255,251,248,1,20,4,1,2,0,0,3,252,2,45,2,239,141,2,1,0,4,1,4,2,2,0,0,0,12,1,20,4,1,2,4,2,2,255,255,255,252,1,20,4,1,1,0,4,1,2,1,4,4,1,4,2,2,0,0,0,8,1,20,4,1,11,1,4,4,1,2,255,255,255,255,2,4,2,2,0,0,0,8,1,20,4,1,1,4,4,1,2,1,8,4,1,4,2,2,0,0,0,16,1,20,4,1,2,4,2,2,255,255,255,248,1,20,4,1,1,8,4,1,2,1,0,4,1,4,2,2,0,0,0,16,1,20,4,1,3,1,0,4,1,2,0,0,0,1,2,4,2,2,0,0,0,16,1,20,4,1,1,0,4,1,6,4,2,2,255,255,255,248,1,20,4,1,2,0,0,0,0,16,2,0,0,28,40,2,1,4,4,1,4,2,2,255,255,255,252,1,20,4,1,10,1,8,4,1,3,1,1,4,4,1,11,1,8,4,1,4,2,2,0,0,0,8,1,20,4,1,17,1,8,4,1,2,0,0,0,255,2,1,0,4,1,4,2,2,0,0,0,8,1,20,4,1,18,1,0,4,1,2,0,0,0,8,11,1,0,4,1,4,3,2,255,255,251,248,1,20,4,1,1,8,4,4,2,4,2,2,0,0,0,8,1,20,4,1,1,0,4,1,2,1,4,4,1,4,2,2,255,255,255,252,1,20,4,1,5,1,4,4,1,2,0,0,0,1,2,4,2,2,255,255,255,252,1,20,4,1,1,4,4,1,8,2,0,0,27,36,2,1,0,4,1,4,2,2,0,0,0,8,1,20,4,1,11,1,0,4,1,2,255,255,255,255,2,1,16,4,1,1,20,4,1,14,1,20,4,1,15,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
    var vm = new VM(mem);
    var loc = vm.stack.getInt32(16) - 38;        
    vm.stack.setInt32(16,loc);
    var flagadd = loc;
    var loc = vm.stack.getInt32(16) - 8;        
    vm.stack.setInt32(16,loc);
    var inputadd = loc;

    mem.set(new TextEncoder("utf-8").encode(input),inputadd);

    vm.push(flagadd);
    vm.push(inputadd);
    vm.push(0xFFFFFFFF);

    try
    {
        while(vm.IP != 0xFFFFFFFF)
        {
            vm.nextInst();
        }
    }
    catch(e)
    {    
    }

    if ( vm.stack.getInt32(0) >= 0 )
        return new TextDecoder("utf-8").decode(mem.subarray(flagadd,flagadd + 37));
    
    return "Failed";
}


Now let's run the script to acquire an execution trace.

GetFlag("maromaro")
web700.html:295 push 0
web700.html:197 mov r1, 11288
web700.html:256 sub 11288, 44
web700.html:295 push 0
web700.html:197 mov r1, 115
web700.html:197 mov r1, 20
web700.html:197 mov r1, 32
web700.html:197 mov r1, 23
web700.html:197 mov r1, 2
web700.html:197 mov r1, 98
web700.html:197 mov r1, 42
web700.html:197 mov r1, 119
web700.html:197 mov r1, 121
web700.html:197 mov r1, 29
web700.html:197 mov r1, 33
web700.html:197 mov r1, 113
web700.html:197 mov r1, 112
web700.html:197 mov r1, 103
web700.html:197 mov r1, 94
web700.html:197 mov r1, 6
web700.html:197 mov r1, 0
web700.html:197 mov r1, 30
web700.html:197 mov r1, 91
web700.html:197 mov r1, 113
web700.html:197 mov r1, 125
web700.html:197 mov r1, 103
web700.html:197 mov r1, 95
web700.html:197 mov r1, 113
web700.html:197 mov r1, 123
web700.html:197 mov r1, 111
web700.html:197 mov r1, 80
web700.html:197 mov r1, 2
web700.html:197 mov r1, 119
web700.html:197 mov r1, 103
web700.html:197 mov r1, 90
web700.html:197 mov r1, 115
web700.html:197 mov r1, 9
web700.html:197 mov r1, 25
web700.html:197 mov r1, 39
web700.html:197 mov r1, 1
web700.html:197 mov r1, 5
web700.html:295 push 8
web700.html:197 mov r1, 11304
web700.html:295 push 11304
web700.html:295 push 305419896
web700.html:188 call, 1223
web700.html:295 push 11288
web700.html:197 mov r1, 11220
web700.html:256 sub 11220, 1032
web700.html:197 mov r1, 0
web700.html:197 mov r1, 1996959894
web700.html:197 mov r1, 3993919788
web700.html:197 mov r1, 2567524794
web700.html:197 mov r1, 124634137
web700.html:197 mov r1, 1886057615
web700.html:197 mov r1, 3915621685
web700.html:197 mov r1, 2657392035
...
...
web700.html:197 mov r1, 3294710456
web700.html:197 mov r1, 1567103746
web700.html:197 mov r1, 711928724
web700.html:197 mov r1, 3020668471
web700.html:197 mov r1, 3272380065
web700.html:197 mov r1, 1510334235
web700.html:197 mov r1, 755167117
2web700.html:197 mov r1, 11304
web700.html:197 mov r1, 305419896
web700.html:246 xor 305419896, 4294967295
web700.html:197 mov r1, 3989547399
web700.html:197 mov r1, 8
web700.html:256 sub 8, 1
web700.html:197 mov r1, 7
web700.html:304 cmp 8, 0
web700.html:197 mov r1, 11304
web700.html:212 movu r1, 109
web700.html:246 xor 109, 3989547399
web700.html:281 and 3989547498, 255
web700.html:197 mov r1, 3989547399
web700.html:235 rsh 3989547399, 8
web700.html:246 xor 15584169, 1088359270
web700.html:197 mov r1, 1077067983
web700.html:197 mov r1, 11304
web700.html:222 add 11304, 1
web700.html:197 mov r1, 11305
web700.html:204 jmp, 6948
web700.html:197 mov r1, 7
web700.html:256 sub 7, 1
web700.html:197 mov r1, 6
web700.html:304 cmp 7, 0
web700.html:197 mov r1, 11305
web700.html:212 movu r1, 97
web700.html:246 xor 97, 1077067983
web700.html:281 and 1077067950, 255
web700.html:197 mov r1, 1077067983
web700.html:235 rsh 1077067983, 8
web700.html:246 xor 4207296, 829329135
web700.html:197 mov r1, 825146415
web700.html:197 mov r1, 11305
web700.html:222 add 11305, 1
web700.html:197 mov r1, 11306
web700.html:204 jmp, 6948
web700.html:197 mov r1, 6
web700.html:256 sub 6, 1
web700.html:197 mov r1, 5
web700.html:304 cmp 6, 0
web700.html:197 mov r1, 11306
web700.html:212 movu r1, 114
web700.html:246 xor 114, 825146415
web700.html:281 and 825146461, 255
web700.html:197 mov r1, 825146415
web700.html:235 rsh 825146415, 8
web700.html:246 xor 3223228, 366619977
web700.html:197 mov r1, 367723509
web700.html:197 mov r1, 11306
web700.html:222 add 11306, 1
web700.html:197 mov r1, 11307
web700.html:204 jmp, 6948
web700.html:197 mov r1, 5
web700.html:256 sub 5, 1
web700.html:197 mov r1, 4
web700.html:304 cmp 5, 0
web700.html:197 mov r1, 11307
web700.html:212 movu r1, 111
web700.html:246 xor 111, 367723509
web700.html:281 and 367723418, 255
web700.html:197 mov r1, 367723509
web700.html:235 rsh 367723509, 8
web700.html:246 xor 1436419, 282753626
web700.html:197 mov r1, 282038617
web700.html:197 mov r1, 11307
web700.html:222 add 11307, 1
web700.html:197 mov r1, 11308
web700.html:204 jmp, 6948
web700.html:197 mov r1, 4
web700.html:256 sub 4, 1
web700.html:197 mov r1, 3
web700.html:304 cmp 4, 0
web700.html:197 mov r1, 11308
web700.html:212 movu r1, 109
web700.html:246 xor 109, 282038617
web700.html:281 and 282038580, 255
web700.html:197 mov r1, 282038617
web700.html:235 rsh 282038617, 8
web700.html:246 xor 1101713, 565507253
web700.html:197 mov r1, 564411172
web700.html:197 mov r1, 11308
web700.html:222 add 11308, 1
web700.html:197 mov r1, 11309
web700.html:204 jmp, 6948
web700.html:197 mov r1, 3
web700.html:256 sub 3, 1
web700.html:197 mov r1, 2
web700.html:304 cmp 3, 0
web700.html:197 mov r1, 11309
web700.html:212 movu r1, 97
web700.html:246 xor 97, 564411172
web700.html:281 and 564411205, 255
web700.html:197 mov r1, 564411172
web700.html:235 rsh 564411172, 8
web700.html:246 xor 2204731, 112637215
web700.html:197 mov r1, 110563620
web700.html:197 mov r1, 11309
web700.html:222 add 11309, 1
web700.html:197 mov r1, 11310
web700.html:204 jmp, 6948
web700.html:197 mov r1, 2
web700.html:256 sub 2, 1
web700.html:197 mov r1, 1
web700.html:304 cmp 2, 0
web700.html:197 mov r1, 11310
web700.html:212 movu r1, 114
web700.html:246 xor 114, 110563620
web700.html:281 and 110563670, 255
web700.html:197 mov r1, 110563620
web700.html:235 rsh 110563620, 8
web700.html:246 xor 431889, 2181625025
web700.html:197 mov r1, 2181981136
web700.html:197 mov r1, 11310
web700.html:222 add 11310, 1
web700.html:197 mov r1, 11311
web700.html:204 jmp, 6948
web700.html:197 mov r1, 1
web700.html:256 sub 1, 1
web700.html:197 mov r1, 0
web700.html:304 cmp 1, 0
web700.html:197 mov r1, 11311
web700.html:212 movu r1, 111
web700.html:246 xor 111, 2181981136
web700.html:281 and 2181981119, 255
web700.html:197 mov r1, 2181981136
web700.html:235 rsh 2181981136, 8
web700.html:246 xor 8523363, 1541320221
web700.html:197 mov r1, 1532797054
web700.html:197 mov r1, 11311
web700.html:222 add 11311, 1
web700.html:197 mov r1, 11312
web700.html:204 jmp, 6948
web700.html:197 mov r1, 0
web700.html:256 sub 0, 1
web700.html:197 mov r1, 4294967295
web700.html:304 cmp 0, 0
web700.html:335 jnz 7208
web700.html:197 mov r1, 1532797054
web700.html:246 xor 1532797054, 4294967295
web700.html:197 mov r1, 11220
web700.html:269 pop
web700.html:265 ret
web700.html:222 add 11228, 12
web700.html:304 cmp 2762170241, 870690368
web700.html:312 jz 903
web700.html:327 or 2762170241, 4294967295
web700.html:269 pop
web700.html:197 mov r1, 11288
web700.html:269 pop
web700.html:265 ret
"Failed"

It is obvious that an encrypted string of size 37 is written in the beginning.
Then many constants are following, yes it is 32-bit CRC lookup table.
The next instructions compute the CRC of 8 bytes input string.

Here is a python implementation of the computation routine:


L = [0,1996959894,...,755167117] 
    
def myH(key):
    r = 305419896 ^ 4294967295  
    for c in key:
        r = ((r & 4294967295) >> 8) ^ L[(r ^ ord(c)) & 0xff]  
    return r ^ 4294967295  


Finally the computed CRC is compared to 870690368 (0x33E5AE40).

We use Z3 to find a 8 bytes string of CRC32 value is 0x33E5AE40.

yjlltzfo is a solution.

Let's run GetFlag("yjlltzfo") and see what happens

In addition to the first trace, we got:

cmp 870690368, 870690368
web700.html:312 jz 903
web700.html:319 [+] Correct Password
2web700.html:197 mov r1, 0
web700.html:204 jmp, 985
web700.html:304 cmp 0, 37
web700.html:197 mov r1, 0
web700.html:212 movu r1, 115
web700.html:197 mov r1, 0
web700.html:246 xor 0, 0
web700.html:197 mov r1, 8
web700.html:345 div 0, 8
web700.html:350 mod 0, 8
web700.html:197 mov r1, 11304
web700.html:212 movu r1, 121
web700.html:246 xor 115, 121
web700.html:197 mov r1, 11312
web700.html:222 add 11312, 0
web700.html:197 mov r1, 10
web700.html:204 jmp, 943
web700.html:197 mov r1, 0
web700.html:222 add 0, 1
web700.html:197 mov r1, 1
web700.html:304 cmp 1, 37
web700.html:197 mov r1, 1
web700.html:212 movu r1, 20
web700.html:197 mov r1, 1
web700.html:246 xor 1, 1
web700.html:197 mov r1, 8
web700.html:345 div 1, 8
web700.html:350 mod 1, 8
web700.html:197 mov r1, 11304
web700.html:212 movu r1, 106
web700.html:246 xor 20, 106
web700.html:197 mov r1, 11312
web700.html:222 add 11312, 1
web700.html:197 mov r1, 126
web700.html:204 jmp, 943
web700.html:197 mov r1, 1
web700.html:222 add 1, 1
web700.html:197 mov r1, 2
web700.html:304 cmp 2, 37
web700.html:197 mov r1, 2
web700.html:212 movu r1, 32
web700.html:197 mov r1, 2
web700.html:246 xor 2, 2
web700.html:197 mov r1, 8
web700.html:345 div 2, 8
web700.html:350 mod 2, 8
web700.html:197 mov r1, 11304
web700.html:212 movu r1, 108
web700.html:246 xor 32, 108
web700.html:197 mov r1, 11312
web700.html:222 add 11312, 2
web700.html:197 mov r1, 76
web700.html:204 jmp, 943
web700.html:197 mov r1, 2
web700.html:222 add 2, 1
web700.html:197 mov r1, 3
web700.html:304 cmp 3, 37
....
"
~L{v L ...

The password was accepted. However we got a garbage string. The entered password is used as a key to decrypt the flag.

According to the trace, here is a python implementation of decryption routine.

flag = [115, 20, 32, 23, 2, 98, 42, 119, 121, 29, 33, 113, 112, 103, 94, 6, 0, 30, 91, 113, 125, 103, 95, 113, 123, 111, 80, 2, 119, 103, 90, 115, 9, 25, 39, 1, 5]    
print "".join([chr(flag[i] ^ ord(password[i % 8])) for i in range(len(flag))])

We should find a valid password which is used to decrypt the flag starting with "KLCTF"

Finally We add the appropriate constraints to Z3 and we put all stuff together.

My solver:


# maro - Pwnium

from z3 import *
   
y = 0xedb88320
    
def H(pwd,size,prev=305419896):
 r = prev ^ 4294967295
 for i in range(0,size,8):
  r = r ^ (z3.LShR(pwd,i) & 0xFF)
  for _ in range(8):
   r = If(r & 1 == BitVecVal(1, size), z3.LShR(r,1) ^ y, z3.LShR(r,1))
 return r ^ 4294967295

size = 8 * 8
s = z3.Solver()
pwd = z3.BitVec('pwd',size)

inf = 32
sup = 126

flag = [115, 20, 32, 23, 2, 98, 42, 119, 121, 29, 33, 113, 112, 103, 94, 6, 0, 30, 91, 113, 125, 103, 95, 113, 123, 111, 80, 2, 119, 103, 90, 115, 9, 25, 39, 1, 5]      

def C(bv):
    return And( (LShR(bv, 0) & 0xff) == ord("K")^ flag[0],
               (LShR(bv, 8) & 0xff) == ord("L")^ flag[1],
               (LShR(bv, 16) & 0xff) == ord("C")^ flag[2],
               (LShR(bv, 24) & 0xff) == ord("T")^ flag[3],                              
               (LShR(bv, 32) & 0xff) == ord("F")^ flag[4],
               inf <= (LShR(bv, 40) & 0xff), (LShR(bv, 40) & 0xff) <= sup,
               inf <= (LShR(bv, 48) & 0xff), (LShR(bv, 48) & 0xff) <= sup,
               inf <= (LShR(bv, 56) & 0xff), (LShR(bv, 56) & 0xff) <= sup,)  


s.add(C(pwd))
s.add(H(pwd,size) == 870690368)

while s.check() == sat:  
    sol =  str(hex(int(str(s.model()[pwd]))))[2:].decode("hex")[::-1]
    print "[+] pwdsword: "+sol
    print "[+] Flag: "+"".join([chr(flag[i] ^ ord(sol[i % 8])) for i in range(len(flag))])
    s.add(Or(pwd != s.model()[pwd]))


The password is 8XcCDUhG and flag is KLCTF7B0AEB2426A8F829276C73A32241ADBA

That's all :))

Follow me on Twitter