swiss hacking challenge 2024 - winning-argument

Posted on May 1, 2024

Difficulty: easy

Category: re

Author: NoRelect

Susan: Hey Steve, do you count from zero or from one?

Files

We get a winning-argument binary.

Exploitation

The decompilation of the program looks rather simple:

int32_t main(int32_t argc, char** argv, char** envp)

{
    *(uint64_t*)argv = __xpg_basename(*(uint64_t*)argv);
    int32_t rax_6;
    if (argc <= 1)
    {
        printf("Usage: %s <input>\n", *(uint64_t*)argv);
        rax_6 = 1;
    }
    else
    {
        int32_t rax_9 = strlen(*(uint64_t*)argv);
        int32_t rax_13 = strlen(argv[1]);
        char* rax_17 = strdup(argv[1]);
        for (int32_t i = 0; i < rax_13; i = (i + 1))
        {
            int32_t temp2_1;
            int32_t temp3_1;
            temp2_1 = HIGHD(((int64_t)i));
            temp3_1 = LOWD(((int64_t)i));
            rax_17[((int64_t)i)] = (*(uint64_t*)argv[((int64_t)(COMBINE(temp2_1, temp3_1) % rax_9))] ^ rax_17[((int64_t)i)]);
        }
        if (memcmp(rax_17, &flag_xored, 0x25) != 0)
        {
            puts("Try bringing better arguments.");
            puts("The current ones don't convince …");
        }
        else
        {
            puts("Congratulations, you have won th…");
            printf("Here is your flag: shc2024{%s}\n", argv[1]);
        }
        rax_6 = 0;
    }
    return rax_6;
}

Basically, if we know the XOR key for the flag, we get the flag. Turns out the complicated for-loop just uses the binary name as the xor key. Meaning we can just decrypt the flag:

from pwn import *
flag = "\x14Y\x1b\x00\x1d\x07\tJ>\x14\x15E\x00:^+\x1e\x1a1\r\x05]S_\r\x0b8\x06\x18\x15]\x06\x1eY\x1cO\x00"
key = "winning-argument"
xor(flag, key)

This gives us the flag!

Flag

shc2024{c0unting_fr0m_0_is_cl34rly_sup3ri0r!i}

Conclusion

Took me some time, but after re-reading the challenge description, the solution was pretty clear.