ДостиТСниС выполнСния ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅ Π½Π°Π΄ тСкстом коммСнтария Π² Python-скриптС

Один ΠΈΠ· участников сорСвнования UIUCTF 2025, ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π», ΠΊΠ°ΠΊ Π΅ΠΌΡƒ ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π·Π°Π΄Π°Π½ΠΈΠ΅, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰Π΅Π΅ Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ исполнСния своСго ΠΊΠΎΠ΄Π° Π½Π° сСрвСрС, имСя лишь Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ измСнСния содСрТимого тСкста коммСнтария Π² ΠΊΠΎΠ΄Π΅.

Участники ΠΌΠΎΠ³Π»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сСтСвой запрос ΠΊ Python-скрипту, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создавал Π½ΠΎΠ²Ρ‹ΠΉ Python-скрипт cΠΎ случайными ΠΈΠΌΠ΅Π½Π΅ΠΌ, добавлял ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠΈΠ΅ ΠΎΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π΄Π°Π½Π½Ρ‹Π΅ Π² тСкст коммСнтария, Π²Ρ‹Ρ€Π΅Π·Π°Π² символы Β«\nΒ» ΠΈ Β«\rΒ», ΠΈ запускал этот скрипт ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Β«python3 имя.pyΒ». ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ содСрТимоС коммСнтария участник Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ строку ΠΈΠ· Ρ„Π°ΠΉΠ»Π° Β«/home/ctfuser/flagΒ». Π‘ΠΊΡ€ΠΈΠΏΡ‚ создавался ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ: comment = input(Β«> Β«).replace(Β«\nΒ», «»).replace(Β«\rΒ», «») code = f»»»print(Β«hello world!Β») # This is a comment. Here’s another: # {comment} print(Β«Thanks for playing!Β»)»»»

ВмСсто Β«{comment}Β» ΠΏΠΎΠ΄ΡΡ‚Π°Π²Π»ΡΠ»ΠΈΡΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠΈΠ΅ ΠΎΡ‚ участника, ΠΈ Π² ΠΈΡ‚ΠΎΠ³Π΅ запускался ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄: print(Β«hello world!Β») # This is a comment. Here’s another: # Π”Π°Π½Π½Ρ‹Π΅, ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠΈΠ΅ ΠΎΡ‚ участника сорСвнования print(Β«Thanks for playing!Β»)

Π—Π°Π΄Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ сформировано ΠΏΠΎ ΠΌΠΎΡ‚ΠΈΠ²Π°ΠΌ уязвимости Π² парсСрС CPython, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π» символ с Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠ΅ строки (ΡƒΡΠ·Π²ΠΈΠΌΠΎΡΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для скрытия врСдоносных дСйствий Π² тСкстС коммСнтария). ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π±Ρ‹Π»Π° устранСна Π² выпусках CPython 3.12.0 ΠΈ 3.11.4. Π’ примСняСмом Π² конкурсС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ Π²Ρ‹Ρ€Π΅Π·Π°Π»ΠΈΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ символы Β«\nΒ» ΠΈ Β«\rΒ», Π½ΠΎ ΠΏΡ€ΠΈ использовании уязвимой вСрсии Π‘Python участник ΠΌΠΎΠ³ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ символ Β«\0Β» ΠΊΠ°ΠΊ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ этот Ρ‚Ρ€ΡŽΠΊ Π½Π΅ сработал Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² конкурсС использовалась ΡƒΠΆΠ΅ исправлСнная вСрсия CPython c расчётом, Ρ‡Ρ‚ΠΎ Π² парсСрС ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ Π΅Ρ‰Ρ‘ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ ошибки ΠΈ участники смогут ΠΈΡ… Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ.

УспСшно ΡΠΏΡ€Π°Π²ΠΈΠ²ΡˆΠΈΠΉΡΡ с Π·Π°Π΄Π°Π½ΠΈΠ΅ΠΌ участник Π½Π΅ стал ΠΈΡΠΊΠ°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ уязвимости Π² парсСрС, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ»ΠΈ Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ строку Π½Π° Ρ‡Π°cΡ‚ΠΈ, Π° воспользовался ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ выполнСния Π² Python Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ ΠΈΡ… содСрТимого. НапримСр, вмСсто исходного ΠΊΠΎΠ΄Π° Π² Ρ„Π°ΠΉΠ» с Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ΠΌ Β«.pyΒ» ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄, сохраняСмый Π² Ρ„Π°ΠΉΠ»Π°Ρ… с Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ΠΌ Β«.pycΒ», ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½. Π’ рассматриваСмом конкурсС участник ΠΌΠΎΠ³ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ содСрТимоС Π² сСрСдинС Ρ„Π°ΠΉΠ»Π°, поэтому Π½Π΅ ΠΌΠΎΠ³ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ свой Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ для искаТСния MIME-Ρ‚ΠΈΠΏΠ°.

Π—Π°Π΄Π°Ρ‡Ρƒ ΡƒΠ΄Π°Π»ΠΎΡΡŒ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, воспользовавшись Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Python начиная с Π²Π΅Ρ‚ΠΊΠΈ 2.6 ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒ содСрТимоС ZIP-Π°Ρ€Ρ…ΠΈΠ²ΠΎΠ² для поставки Python-ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² Π² сТатом Π²ΠΈΠ΄Π΅. Как ΠΈ Π² случаС с кэшСм Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ zip-Π°Ρ€Ρ…ΠΈΠ²Π° опрСдСляСтся ΠΏΠΎ содСрТимому, Π° Π½Π΅ ΠΏΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡŽ Ρ„Π°ΠΉΠ»Π°, Ρ‚.Π΅. Π² Β«Ρ„Π°ΠΉΠ».pyΒ» ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ zip-Π°Ρ€Ρ…ΠΈΠ² ΠΈ ΠΏΡ€ΠΈ запускС ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Β«python Ρ„Π°ΠΉΠ».pyΒ» ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½, ΠΊΠ°ΠΊ сТатый Python-ΠΏΠ°ΠΊΠ΅Ρ‚. ΠŸΡ€ΠΈ этом ZIP-Π°Ρ€Ρ…ΠΈΠ²Ρ‹ Π² Python ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π΅ ΠΏΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΡƒ Π² Π½Π°Ρ‡Π°Π»Π΅ Ρ„Π°ΠΉΠ»Π°, Π° ΠΏΠΎ сСкции EOCD (End of Central Directory Record) Π² ΠΊΠΎΠ½Ρ†Π΅ Ρ„Π°ΠΉΠ»Π°. ΠŸΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π² Π°Ρ€Ρ…ΠΈΠ²Π΅ Ρ„Π°ΠΉΠ»Π° Β«__main__.pyΒ», этот Ρ„Π°ΠΉΠ» запускаСтся автоматичСски ΠΏΡ€ΠΈ прямом запускС Π°Ρ€Ρ…ΠΈΠ²Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Β«python Π°Ρ€Ρ…ΠΈΠ²Β».

ΠšΠΎΠ½ΠΊΡƒΡ€ΡΠ½Π°Ρ Π·Π°Π΄Π°Ρ‡Π° Π±Ρ‹Π»Π° Ρ€Π΅ΡˆΠ΅Π½Π° Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ZIP-Π°Ρ€Ρ…ΠΈΠ²Π° ΠΈ подстановкой Π΅Π³ΠΎ Π² тСкст коммСнтария. Для сохранСния коррСктности структуры Ρ„Π°ΠΉΠ»Π° Π² условиях наличия Π² ΠΊΠΎΠ½Ρ†Π΅ исходного Ρ„Π°ΠΉΠ»Π° Π²Ρ‹Π·ΠΎΠ²Π° β€˜print(Β«Thanks for playing!Β»)’, Π±Ρ‹Π»ΠΎ использовано Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π² EOCD-сСкции области коммСнтария, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅ΠΌΠΎΠΉ Π² самом ΠΊΠΎΠ½Ρ†Π΅.

 ДостиТСниС выполнСния ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅ Π½Π°Π΄ тСкстом коммСнтария Π² Python-скриптС
 ДостиТСниС выполнСния ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅ Π½Π°Π΄ тСкстом коммСнтария Π² Python-скриптС


Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: opennet.ru

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ