Published on

BuckeyeCTF 2023 – 8ball

Authors
  • avatar
    Name
    Lumy
    Twitter

8Ball

Let me guide you to the flag.

Table of Contents

  1. Source code
  2. Solution

Source code

The description gives us a zip file containg the source of the challenge : 8ball

Solution

Here is desassembly of the main function using BinaryNinja :

int32_t main(int32_t argc, char** argv, char** envp)
    setvbuf(fp: stdout, buf: nullptr, mode: 2, size: 0)
    srand(x: time(nullptr))
    if (argc != 2)
        puts(str: "Every question has answer... if …")
        printf(format: "Go ahead, ask me anything.\n", *argv)
        exit(status: 0)
        noreturn
    int32_t var_c = 0
    if (strcmp(*argv, "./magic8ball") == 0)
        puts(str: "Why, I guess you're right... I a…")
        var_c = 1
    void var_168
    __builtin_memcpy(dest: &var_168, src: 0x4024a0, n: 0x140)
    puts(str: "You asked:")
    printf(format: ""%s"\n", argv[1])
    printf(format: "Hmmm", 0)
    putchar(c: 0x2e)
    putchar(c: 0x2e)
    putchar(c: 0x2e)
    puts(str: &data_4020c1)
    char* rax_15
    if (var_c != 0)
        rax_15 = strstr(argv[1], "flag")
        if (rax_15 != 0)
            puts(str: "Why yes, here is your flag!")
            print_flag()
    if (var_c == 0 || (var_c != 0 && rax_15 == 0))
        puts(str: *(&var_168 + (sx.q((modu.dp.q(0:(sx.q(rand())), 0x28)).d) << 3)))
    return 0

We can see a print_flag() function. Let's see what's inside :

int64_t print_flag()
    int64_t var_48
    __builtin_memcpy(dest: var_48, src: "\xa1\x8f\xd7\xb2\xf2\xfaH9k\xc2\x92\x10XDe\x8cJuV\x0bfQh\x89\x8d\x0c\xfd\x8dg\"\xdf\x0f\xca\x8f\x9b%\xb9", n: 0x25)
    int64_t var_78
    __builtin_memcpy(dest: var_78, src: "\xaa/\xe5X\xb8j<3\x15\xd6XB81b\xde\xcd\xa4\xe9\xb8\xe8\xbd\xfcw\xa2\x89z\xc1\xa2\xda37\xd8K\x9d\xb9\x14", n: 0x25)
    for (int32_t var_c = 0x24; var_c s> 0; var_c = var_c - 1)
        *(&var_78 + sx.q(var_c)) = *(&var_78 + sx.q(var_c - 1)) ^ *(&var_78 + sx.q(var_c))
    int32_t var_10 = 0
    while (sx.q(var_10) u< 0x25)
        *(&var_78 + sx.q(var_10)) = *(&var_78 + sx.q(var_10)) ^ 0x69
        var_10 = var_10 + 1
    int32_t var_14 = 0
    while (sx.q(var_14) u< 0x25)
        *(&var_78 + sx.q(var_14)) = *(&var_48 + sx.q(var_14)) ^ *(&var_78 + sx.q(var_14))
        var_14 = var_14 + 1
    return puts(str: &var_78)

We can convert this code to python :

var_48 = bytearray(b"\xa1\x8f\xd7\xb2\xf2\xfaH9k\xc2\x92\x10XDe\x8cJuV\x0bfQh\x89\x8d\x0c\xfd\x8dg\"\xdf\x0f\xca\x8f\x9b%\xb9")
var_78 = bytearray(b"\xaa/\xe5X\xb8j<3\x15\xd6XB81b\xde\xcd\xa4\xe9\xb8\xe8\xbd\xfcw\xa2\x89z\xc1\xa2\xda37\xd8K\x9d\xb9\x14")

for var_c in range(0x24, 0, -1):
    var_78[var_c] = var_78[var_c] ^ var_78[var_c - 1]

var_10 = 0
while var_10 < 0x25:
    var_78[var_10] = var_78[var_10] ^ 0x69
    var_10 = var_10 + 1

var_14 = 0
while var_14 < 0x25:
    var_78[var_14] = var_48[var_14] ^ var_78[var_14]
    var_14 = var_14 + 1

result = bytes(var_78).decode("latin-1")
print(result)

#output : bctf{Aw_$hucK$_Y0ur3_m@k1Ng_m3_bLu$h}

Flag : : bctf{Aw_$hucK$_Y0ur3_m@k1Ng_m3_bLu$h}