Koodi käitamise saavutamine Python-skripti kommentaariteksti üle kontrolli all

Üks UIUCTF 2025 konkursi osalejatest selgitas üksikasjaliselt, kuidas talle õnnestus täita ülesanne, mis nõudis oma koodi teostamist serveris, omades vaid võimalust muuta koodis kommentaariteksti sisu.

Osalejad said saata võrgu päringu Python-skripti, mis lõi uue Python-skripti juhusliku nimega, lisas kasutajalt saadud andmed kommentaariteksti, eemaldades sümbolid «\n» ja «\r», ning käivitas selle skripti käsuga «python3 nimi.py». Kontrollides ainult kommentaari sisu, pidi osaleja võtma faili «/home/ctfuser/flag» rea. Skripti loodi järgmise koodiga: comment = input(«> «).replace(«\n», «»).replace(«\r», «») code = f»»»print(«hello world!») # See on kommentaar. Siin on veel üks: # {comment} print(«Thanks for playing!»)»»»

Kohandati andmeid, mis said osalejalt, ja lõpuks käivitus järgmine kood: print(«hello world!») # See on kommentaar. Siin on veel üks: # Konkursi osalejalt saadud andmed print(«Thanks for playing!»)

Ülesanne oli koostatud CPythoni parseris esinenud haavatavuse põhjal, mis käsitles nullkoodi sümbolit ridade lõpetamisena (näiteks võis seda haavatavust kasutada pahatahtlike toimingute varjamiseks kommentaaritekstis). Probleem lahendati CPython versioonides 3.12.0 ja 3.11.4. Võistluses kasutatavas töötlejas eemaldati ainult sümbolid "\n" ja "\r", kuid haavatava CPython versiooni kasutamisel sai osaleja kasutada sümbolit "\0" eraldajana. Sellegipoolest see trikk ei töötanud, kuna konkursil kasutati juba parandatud versiooni CPythonist, arvestades, et parseris võivad jääda veel sarnased vead, mida osalejad saavad tuvastada.

Ülesande edukalt täitnud osaleja ei hakanud otsima uusi haavatavusi parseris, mis võimaldaksid jagada rida osadeks, vaid kasutas Pythonis failide täitmise eripära vastavalt nende sisule. Näiteks võib algkoodi asemel failis, millel on laiend «.py», asetada vahemällu salvestatud koondkäskude koodi, mis on talletatud failides laiendiga «.pyc», ja selline fail saab täidetud. Arutletavas konkursis suutis osaleja kontrollida ainult faili keskosa sisu, seetõttu ei saanud ta lisada oma pealkirja, et rikutaks MIME tüüpi.

Probleemi sai lahendatud, kasutades asjaolu, et Python alates versioonist 2.6 suudab ZIP-arhiivide sisu käitada, et pakkuda Python-pakette komprimeeritud kujul. Nii nagu selle puhul, kui on tegemist bytecode'i vahemäluga, määratakse ZIP-arhiivi olemasolu sisu, mitte faili laiendi järgi, st faili «fail.py» saab panna ZIP-arhiivi ning käivitamisel käsuga «python fail.py» töödeldakse seda komprimeeritud Python-paketina. Samuti ei indekseeritakse ZIP-arhiive Pythonis faili alguse pealkirja, vaid faili lõpu EOCD (End of Central Directory Record) sektsiooni järgi. Kui arhiivis on fail «__main__.py», käivitatakse see automaatselt arhiivi käsitsi käivitamisel käsuga «python arhiiv».

Konkursiteema lahendati sarnase ZIP-arhiivi genereerimise ja selle subjekteerimisega kommentaari tekstis. Failistruktuuri struktuuri säilitamiseks, olles algsesse faili lisatud «print(«Thanks for playing!»)», kasutati EOCD-sektsiooni kommentaaride ala olemasolu, mis asub faili lõpus.

Koodi käitamise saavutamine Python-skripti kommentaariteksti üle kontrolli all
Koodi käitamise saavutamine Python-skripti kommentaariteksti üle kontrolli all


Allikas: opennet.ru
Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster