LOAD_NAME / LOAD_CONST opcode OOB Read
Last updated
Last updated
Jifunze & zoezi AWS Hacking:Mafunzo ya HackTricks AWS Timu Nyekundu Mtaalam (ARTE) Jifunze & zoezi GCP Hacking: Mafunzo ya HackTricks GCP Timu Nyekundu Mtaalam (GRTE)
Maelezo haya yalichukuliwa kutoka kwenye andiko hili.
Tunaweza kutumia kipengele cha OOB soma katika opcode ya Kusoma_JINA / Kusoma_CONST ili kupata alama fulani kwenye kumbukumbu. Hii inamaanisha kutumia hila kama (a, b, c, ... mamia ya alama ..., __getattribute__) if [] else [].__getattribute__(...)
ili kupata alama (kama vile jina la kazi) unayotaka.
Kisha tengeneza shambulio lako.
Msimbo wa chanzo ni mfupi sana, una jumla ya mistari 4!
Unaweza kuingiza kanuni ya Python ya kupita, na itakusanywa kuwa kitu cha kanuni ya Python. Walakini co_consts
na co_names
ya kitu hicho cha kanuni itabadilishwa na tuple tupu kabla ya kutekeleza kitu hicho cha kanuni.
Kwa njia hii, mizunguko yote inayojumuisha consts (k.m. nambari, herufi n.k.) au majina (k.m. vitu, kazi) inaweza kusababisha kosa la segemantasi mwishowe.
Jinsi gani kosa la segemantasi linatokea?
Tuanze na mfano rahisi, [a, b, c]
inaweza kukusanywa kuwa bytecode ifuatayo.
Lakini ikiwa co_names
itakuwa tuple tupu? OPCODE ya LOAD_NAME 2
bado inatekelezwa, na jaribu kusoma thamani kutoka kwa anwani ya kumbukumbu ambayo kimsingi inapaswa kuwa. Ndiyo, hii ni kusoma nje ya mipaka "sifa".
Mfumo msingi wa suluhisho ni rahisi. Baadhi ya opcodes katika CPython kwa mfano LOAD_NAME
na LOAD_CONST
wako katika hatari (?) ya kusoma nje ya mipaka.
Hupata kitu kutoka kwa index oparg
kutoka kwa tuple za consts
au names
(hizo ndizo zinaitwa co_consts
na co_names
chini ya pazia). Tunaweza kurejelea snippest fupi ifuatayo kuhusu LOAD_CONST
kuona CPython inafanya nini wakati inaprocess hadi OPCODE ya LOAD_CONST
.
Kwa njia hii tunaweza kutumia kipengele cha OOB kupata "jina" kutoka kwa mbadala wa kumbukumbu. Ili kuhakikisha jina lina nini na ni mbadala gani, jaribu tu LOAD_NAME 0
, LOAD_NAME 1
... LOAD_NAME 99
... Na unaweza kupata kitu karibu na oparg > 700. Unaweza pia kujaribu kutumia gdb kuangalia muundo wa kumbukumbu bila shaka, lakini siamini itakuwa rahisi zaidi?
Marafiki tunapopata vipande muhimu kwa majina / mbadala, vipi tunavyoweza kupata jina / mbadala kutoka kwa mbadala huo na kulitumia? Hapa kuna hila kwako:
Hebu tufikirie tunaweza kupata jina la __getattribute__
kutoka kwa mbadala 5 (LOAD_NAME 5
) na co_names=()
, basi fanya mambo yafuatayo:
Tafadhali fahamu kwamba si lazima kuiita kama
__getattribute__
, unaweza kuipa jina fupi au la kipekee zaidi
Unaweza kuelewa sababu nyuma yake kwa kuangalia bytecode yake:
Tambua kwamba LOAD_ATTR
pia hurejesha jina kutoka co_names
. Python huload majina kutoka kwa offset ile ile ikiwa jina ni sawa, hivyo __getattribute__
ya pili bado inapakiwa kutoka offset=5. Kwa kutumia kipengele hiki tunaweza kutumia jina lolote mara tu jina linapo karibu na kumbukumbu.
Kwa kuzalisha nambari inapaswa kuwa rahisi:
0: sio [[]]
1: sio []
2: (sio []) + (sio [])
...
Sikutumia consts kutokana na kikomo cha urefu.
Kwanza hapa kuna skripti ili tuweze kupata hizo offsets za majina.
Na yafuatayo ni kwa ajili ya kuzalisha shambulizi la Python halisi.
Inafanya mambo yafuatayo, kwa hizo herufi tunazipata kutoka kwa njia ya __dir__
:
Jifunze na zoea AWS Hacking:Mafunzo ya HackTricks kwa Wataalam wa Timu Nyekundu ya AWS (ARTE) Jifunze na zoea GCP Hacking: Mafunzo ya HackTricks kwa Wataalam wa Timu Nyekundu ya GCP (GRTE)