Vector Fun

Vectors are my favorite Zeek type. Vectors of any are full of surprises. Place your guess for the flag in the your_guess variable and invoke the script to see if you guessed correctly.

Original provided source code.

# Set your guess and run the script to see if you guessed correctly.

global your_guess: string = "" &redef;

global v: vector of any = {"Kjjm=", 8, "VGhl", -1, "0lz", "HbL", "Rs==", 9, "VGhpc", "ZzIy", 3, 12, "2Jc", "Mw==", "Rmxh", function(): count { return 13; }, "kr1", 14};
your_guess = encode_base64(your_guess);
if (your_guess[20:24] == (v[(v[15] as function(): count)()] as string)) { if (your_guess[5:8] == (v[4] as string)) { if (your_guess[12:16] == (v[(v[(v[3] as int):][0] as count)] as string)) { if (your_guess[16:20] == (v[(v[7] as count)] as string)) { if (your_guess[0:5] == (v[(v[1] as count)] as string)) { if (your_guess[8:12] == (v[(10 - (v[1] as count))] as string)) {
  print "your guess was right!";
}}}}}}

Let us take a look when properly formatted.

# Set your guess and run the script to see if you guessed correctly.

global your_guess: string = "" &redef;

global v: vector of any = {
    "Kjjm=", 8,
     "VGhl",
     -1,
     "0lz",
     "HbL",
     "Rs==",
     9,
     "VGhpc",
     "ZzIy",
     3,
     12,
     "2Jc",
     "Mw==",
     "Rmxh",
     function(): count { return 13; },
     "kr1",
     14
};
your_guess = encode_base64(your_guess);
if (your_guess[20:24] == (v[(v[15] as function(): count)()] as string)) {
    if (your_guess[5:8] == (v[4] as string)) {
        if (your_guess[12:16] == (v[(v[(v[3] as int):][0] as count)] as string)) {
            if (your_guess[16:20] == (v[(v[7] as count)] as string)) {
                if (your_guess[0:5] == (v[(v[1] as count)] as string)) {
                    if (your_guess[8:12] == (v[(10 - (v[1] as count))] as string)) {
                        print "your guess was right!";
                    }
                }
            }
        }
    }
}


We have a base64 encoded string (your guess) and uses a vector of any, which can be an ordered collection of type string, count, and even an anonymous function.

It slices up the string and compares those slices to string computed from the vector.

I noticed the slice comparisons are nicely aligned, and nested, so I just reorganized the computation and append the chunks to a string in the correct order from the inside out, and decode.

Note the typecasting usage in order to evaluate values from the vector.

Note the function typecast with return type and the subsuquent function evaluation on line #25.

redef exit_only_after_terminate = F;

global v: vector of any = {
    "Kjjm=",
    8,
    "VGhl",
    -1,
    "0lz",
    "HbL",
    "Rs==",
    9,
    "VGhpc",
    "ZzIy",
    3,
    12,
    "2Jc",
    "Mw==",
    "Rmxh",
    function(): count { return 13; },
    "kr1",
    14
};

event zeek_init() {
    local msg: string = "";
    msg += (v[(v[1] as count)] as string);
    msg += (v[4] as string);
    msg += (v[(10 - (v[1] as count))] as string);
    msg += (v[(v[(v[3] as int):][0] as count)] as string);
    msg += (v[(v[7] as count)] as string);
    msg += (v[(v[15] as function(): count)()] as string);
    print decode_base64(msg);
}

The solution

ThisIsTheFlag223

Last updated