Initially I opened the binary with Ghidra and IDA to view the disassembly and decompiled code. But I didn't really manage to find anything (pretty sure I didn't look correctly). I then used gdb to debug the program.

Solution

  1. Using gdb (GNU Debugger)

    bread is a stripped binary, meaning the debugging symbols have been discarded during the compilation of the binary. For example, in the previous challenges, we were able to set a breakpoint at "main" easily (b *main). However, for stripped binaries, the symbol "main" cannot be found and we would have to source around for it. This is a good link to learn how to debug with stripped binaries. Usually this method would work, however for this binary, it didn't work. Instead, I put breakpoints at functions I knew would definitely be called (like strcmp and puts).

    Immediately after the user input, a string comparison was happening.

    This meant that the first ingredient was "add flour". With that in mind, I ran the program again hoping the next strcmp would give me the next ingredient. Unfortunately, that did not happen(?)

  2. Open the binary with CyberChef.

    The strings within the binary are printed out and "add flour" was one of the strings. "flag.txt" also appeared, so I created a file called "flag.txt" and placed an arbitrary flag inside it.

    I think that all the ingredients needed are within this chunk of text. We just need to figure out which it is. It was a long process and it's best to write a script as there is a timeout. The ingredient can be figured out by seeing which phrase makes the most sense depending on the context.

  3. Write a script.

    from pwn import *
    
    p = remote("mc.ax", 31796)
    
    p.sendlineafter("bowl", "add flour")
    p.sendlineafter("flour has been added", "add yeast")
    p.sendlineafter("yeast has been added", "add salt")
    p.sendlineafter("salt has been added", "add water")
    p.sendlineafter("lumpy dough", "hide the bowl inside a box")
    p.sendlineafter("to rise", "wait 3 hours")
    p.sendlineafter("finish the dough", "work in the basement")
    p.sendlineafter("needs to be baked", "preheat the toaster oven")
    p.sendlineafter("for 45 minutes", "set a timer on your phone")
    p.sendlineafter("awfully long time", "watch the bread bake")
    p.sendlineafter("no time to waste", "pull the tray out with a towel")
    p.sendlineafter("smoke in the air", "unplug the fire alarm")
    p.sendlineafter("in another room", "open the window")
    p.sendlineafter("air rushes in", "unplug the oven")
    p.sendlineafter("kitchen is a mess", "wash the sink")
    p.sendlineafter("sink is cleaned", "clean the counters")
    p.sendlineafter("counters are cleaned", "flush the bread down the toilet")
    p.sendlineafter("is disposed of", "get ready to sleep")
    p.sendlineafter("go to sleep", "close the window")
    p.sendlineafter("window is closed", "replace the fire alarm")
    p.sendlineafter("alarm is replaced", "brush teeth and go to bed")
    p.interactive()
    p.close()
    

    After running this script, the flag can be found.

Flag: flag{m4yb3_try_f0ccac1a_n3xt_t1m3???0r_dont_b4k3_br3ad_at_m1dnight}