Yaml python biblioteke takođe mogu da deserijalizuju python objekte a ne samo sirove podatke:
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
Proverite kako tuple nije sirovi tip podataka i zbog toga je bio serijalizovan. Isto se desilo sa range (preuzeto iz ugrađenih funkcija).
safe_load() ili safe_load_all() koriste SafeLoader i ne podržavaju deserijalizaciju objekata klase. Primer deserijalizacije objekata klase:
import yamlfrom yaml import UnsafeLoader, FullLoader, Loaderdata =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
Prethodni kod je koristio unsafe_load da učita serijalizovanu python klasu. Ovo je zato što u verziji >= 5.1, ne dozvoljava da se deserijalizuje bilo koja serijalizovana python klasa ili atribut klase, sa Loaderom koji nije naveden u load() ili Loader=SafeLoader.
Napomena da u novijim verzijama više ne možete pozvati .load()bez Loader-a i FullLoader više nije ranjiv na ovaj napad.
RCE
Prilagođeni payload-ovi mogu biti kreirani korišćenjem Python YAML modula kao što su PyYAML ili ruamel.yaml. Ovi payload-ovi mogu iskoristiti ranjivosti u sistemima koji deserijalizuju nepouzdan unos bez odgovarajuće sanizacije.