Write-up Infinity Gauntlet (angstromctf)
User1
Insert cookie to continue @ch4nnel1
Content:
Analysis

When the program starts, it offers to guess the result of either one of the arguments of some function: bar() or foo().

After exploring the asm code a bit, you can imagine an example pseudocode of functions.
bar(a, b, c):
return b*(c+1)+a
foo(a, b):
return (a^1337)^(b+1)
Using knowledge of rocket science and post-quantum cryptography, we will write a function of a similar function rev_in() from this script, which will be able to restore any missing numbers. Somehow by automating the sending of responses and communication with the server (for example, using pwntools). We will go through many rounds and understand that it does not want to give the flag ...

After reading the asm code a little more, we will see that the flag is somehow given to us after the 50th round. More precisely, each letter of the flag is first xored according to this algorithm.
flag="actf{...}"
for i in range(len(flag)):
flag[i]^=(0x11*i)%256
And then (after round 50) in the low byte of the correct answer there is a random encrypted flag symbol. So yes, we were able to get the flag, but we have several problems: the flag is encrypted and we don't know the order in which the received bytes make up the flag. But, but if you look at how the random works in this binary, you can understand that since its seed is set as time(0) => you can restore the sequence of the received random numbers => restore the flag sequence.
But I did a little differently, firstly, I ran this script in the provided shell (this was done on their server in order to have a minimal difference in the time that the binary uses and that issues the script)

Let's find the time that the binary used, for this I used this script, in it you need to specify the time and the first ebx value that the previous script returned to us, we get the seed that was used to generate the random (for me it coincided with the time that the first script issued).
Then I hardcoded this seed into a binar by patching it.

Next, creating a file flag.txt filled with 25 zeros, 25 zeros, since there are only 25 different ones in the encrypted flag bytes. And by running the same first script, but specifying the already patched version of the binary, we will get bytes with which, you can restore the sequence of flag chars => and the flag itself.
To do this, I used another script

Solution
- after reading the asm, understand how foo() and bar() work
- write a program that will be able to solve server problems (don't get a flag, it will be upset)
- reverse some more, see that the encrypted flag is issued after 50 rounds in random order
- notice the "weak" random, exploit it -> find out the order in which the encrypted bytes of flag should be
- recover flag
Epilogue
In general, the first two points can be dropped from the solution, since by installing the correct seed on the local binary, you can get the same values as on the remote one, simply by reading them from the program memory. But in the beginning, I did not plan to exploit the "weak" random, and implemented them, which is why I mentioned them (points) in the report.