A box of chocolate

my public personal notebook

Whitehat Contest 11 RE2

We are given a Golang binary, which my idol teammate @yeuchimse reverse engineered :3. The checking code looks like this:

factorials = [1, 1, 2, 6, 0x18, 0x78, 0x2d0, 0x13b0, 0x9d80, 0x58980, 0x375f00, 0x2611500, 0x1c8cfc00]

def calc(nums):
    nums = [0] + nums
    pos_arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    j = 1

    result = 1
    while True:
        n = nums[j]
        n_index = pos_arr[n] - 1
        y = len(nums) - 1 - j
        result += factorials[y] * n_index

        for i in xrange(nums[j] + 1, len(nums)):
            pos_arr[i] -= 1

        j += 1
        if j == len(nums):
            break

    print result

    # assert result == 0xE37F550

The result += factorials[y] * n_index part kinds of remind me about factoradic numbers, which can be used to number and calculate permutations lexicographically. And this function takes a list as its input and calculates a number. Maybe it is used to convert a factoradic number to a decimal number? But the algorithm seems more complicated than that. So we tried to put a permutation to that function, and voila! It returns the index of that permutation!

So the problem became finding a permutation given its index. We can implement it following this nice tutorial here, but I ended up reuse the code I wrote some times ago here (it's written in Pascal and there are no comments, sorry about that :( ).

The flag is 612945128107113.