LOAD_NAME / LOAD_CONST opcode OOB Read
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Hii taarifa ilichukuliwa kutoka kwa andiko hili.
Tunaweza kutumia kipengele cha OOB read katika LOAD_NAME / LOAD_CONST opcode kupata alama fulani katika kumbukumbu. Hii inamaanisha kutumia hila kama (a, b, c, ... mamia ya alama ..., __getattribute__) if [] else [].__getattribute__(...)
kupata alama (kama vile jina la kazi) unayotaka.
Kisha tengeneza tu exploit yako.
Msimbo wa chanzo ni mfupi sana, unajumuisha mistari 4 tu!
You can input arbitrary Python code, and it'll be compiled to a Python code object. However co_consts
and co_names
of that code object will be replaced with an empty tuple before eval that code object.
Hivyo kwa njia hii, kila expression inayo na consts (mfano: nambari, nyuzi n.k.) au majina (mfano: mabadiliko, kazi) inaweza kusababisha segmentation fault mwishoni.
Segfault inatokea vipi?
Tuanzie na mfano rahisi, [a, b, c]
inaweza kukusanywa kuwa bytecode ifuatayo.
Lakini je, ni nini kitakachotokea ikiwa co_names
itakuwa tuple tupu? Opcode LOAD_NAME 2
bado inatekelezwa, na inajaribu kusoma thamani kutoka kwa anwani hiyo ya kumbukumbu ambayo awali ilipaswa kuwa. Ndio, hii ni "kipengele" cha kusoma nje ya mipaka.
Dhana kuu ya suluhisho ni rahisi. Opcode zingine katika CPython kama LOAD_NAME
na LOAD_CONST
zina udhaifu (?) kwa kusoma nje ya mipaka.
Zinapata kitu kutoka kwa index oparg
kutoka kwa tuple ya consts
au names
(hivyo ndivyo co_consts
na co_names
zinavyoitwa kwa ndani). Tunaweza kurejelea kipande kifupi kuhusu LOAD_CONST
ili kuona kile CPython inachofanya wakati inashughulikia opcode ya LOAD_CONST
.
Kwa njia hii tunaweza kutumia kipengele cha OOB kupata "jina" kutoka kwa ofset ya kumbukumbu isiyo ya kawaida. Ili kuhakikisha ni jina gani lina, na ni ofset gani, endelea kujaribu LOAD_NAME 0
, LOAD_NAME 1
... LOAD_NAME 99
... Na unaweza kupata kitu katika takriban oparg > 700. Unaweza pia kujaribu kutumia gdb kuangalia mpangilio wa kumbukumbu bila shaka, lakini sidhani kama itakuwa rahisi zaidi?
Mara tu tunapopata hizo ofset muhimu za majina / consts, tuna vipi kupata jina / const kutoka kwa ofset hiyo na kulitumia? Hapa kuna ujanja kwako:
Tuchukulie tunaweza kupata jina la __getattribute__
kutoka ofset 5 (LOAD_NAME 5
) na co_names=()
, kisha fanya mambo yafuatayo:
Kumbuka kwamba si lazima kuipa jina kama
__getattribute__
, unaweza kuipa jina la kifupi zaidi au la ajabu zaidi
Unaweza kuelewa sababu nyuma yake kwa kutazama bytecode yake:
Kumbuka kwamba LOAD_ATTR
pia inapata jina kutoka co_names
. Python inachukua majina kutoka kwa offset sawa ikiwa jina ni sawa, hivyo __getattribute__
ya pili bado inachukuliwa kutoka offset=5. Kutumia kipengele hiki tunaweza kutumia jina lolote mara jina likiwa katika kumbukumbu karibu.
Kwa ajili ya kuzalisha nambari inapaswa kuwa rahisi:
0: si [[]]
1: si []
2: (si []) + (si [])
...
Sikutumia consts kutokana na kikomo cha urefu.
Kwanza hapa kuna script ya kutusaidia kupata offsets hizo za majina.
Na yafuatayo ni kwa ajili ya kuzalisha exploit halisi ya Python.
Inafanya mambo yafuatayo, kwa ajili ya nyuzi hizo tunazipata kutoka kwa njia ya __dir__
:
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)