swiss hacking challenge 2024 - printer-manual

Posted on May 1, 2024

Difficulty: baby

Category: re

Author: NoRelect

Have you ever had problems with your printer?

Fear not, because in this manual, you can unlock some secret tips to deal with all potential issues for the XYZ-1000 printer model using an interactive application.

Files

We are provided with a printer-manual executable:

$ file printer-manual
printer-manual: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d5c1de9acbe33bee85bb90e0e8c8180a58a24c98, for GNU/Linux 3.2.0, not stripped

Exploitation

Decompiling the program reveals the following code:

int32_t main(int32_t argc, char** argv, char** envp)
{
    int32_t argc_1 = argc;
    char** argv_1 = argv;
    puts("Printer User Manual: Model XYZ-1…");
    puts("================================…");
    puts("Congratulations on your purchase…");
    puts("We're excited to introduce you t…");
    puts("Please keep in mind that while w…");
    puts("we cannot guarantee that the pri…");
    puts("Section 1: Getting Started");
    puts("--------------------------------…");
    puts("Question 1: Have you plugged in …");
    if (did_type_yes() == 0)
    {
        response_count = (response_count * 3);
        puts("Kindly reconsider your decision …");
    }
    else
    {
        response_count = (response_count * 2);
        puts("Proceed to Question 2.");
    }
    puts("Question 2: Is the printer turne…");
    if (did_type_yes() == 0)
    {
        puts("Please locate the power button a…");
        puts("If you cannot find the power but…");
        puts("It's probably hidden somewhere i…");
        response_count = (response_count * 7);
    }
    else
    {
        puts("Congratulations! You've mastered…");
        response_count = (response_count * 5);
    }
    puts("Section 2: Ink Cartridge Install…");
    puts("--------------------------------…");
    puts("Question 1: Do you have ink cart…");
    if (did_type_yes() == 0)
    {
        puts("Please ponder the meaning of lif…");
        response_count = (response_count * 13);
    }
    else
    {
        puts("Proceed to Question 2.");
        response_count = (response_count * 11);
    }
    puts("Question 2: Are the ink cartridg…");
    if (did_type_yes() == 0)
    {
        puts("Don't worry, we're used to disap…");
        puts("Please refer to the list of comp…");
        response_count = (response_count * 19);
    }
    else
    {
        puts("Congratulations again! You're on…");
        response_count = (response_count * 17);
    }
    puts("Section 3: Troubleshooting");
    puts("--------------------------------…");
    puts("Question 1: Is the printer refus…");
    if (did_type_yes() == 0)
    {
        puts("We don't believe you. Please dou…");
        response_count = (response_count * 29);
    }
    else
    {
        puts("Welcome to the club. It's not yo…");
        response_count = (response_count * 23);
    }
    puts("Question 2: Have you tried turni…");
    if (did_type_yes() == 0)
    {
        puts("Please try it. It's the universa…");
        response_count = (response_count * 37);
    }
    else
    {
        puts("Did it work?");
        puts("    If yes, you're a wizard. Ple…");
        puts("    If no, join the club again. …");
        response_count = (response_count * 31);
    }
    puts("Section 4: Final Thoughts");
    puts("--------------------------------…");
    puts("Congratulations, you've complete…");
    puts("We hope this manual has been som…");
    puts("Remember, printers are like unre…");
    puts("but they'll always manage to dis…");
    puts("Happy printing... or not.\n");
    puts("Section 5: Hidden guide");
    puts("--------------------------------…");
    if (response_count != 2227918)
    {
        puts("Not unlocked. Good luck on your …");
    }
    else
    {
        printf("Something that nobody knows abou…", getenv("FLAG"));
    }
    return 0;
}

We notice that based on yes/no statements, the response_count variable is multiplied by different integers. If we make the correct choices, we get a flag.

The easiest way to get the correct target values is to just calculate the prime factors, for example using sagemath:

sage: factor(2227918)
2 * 7 * 11 * 17 * 23 * 37

Based on the code this means we have to answer in the following way:

  • yes
  • no
  • yes
  • yes
  • yes
  • no

Upon doing that on the remote, we get the flag:

Flag

shc2024{XYZ-1000_i5_th3_b35t_pr1nt3r_0ut_th3r3!}

Conclusion

“I’ve heard you work in IT, can you help me fix my printer?”