# Controlled address leak due to type confusion - ASLR bypass

mruby's String#<=> treats an overridden comparator's returned object as a fixnum, leaking the string object's heap address and defeating ASLR.

- Payout: hidden
- Severity: medium
- Program: Shopify
- Found by: aerodudrizzt
- Disclosed: 2017-03-14
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/207321
- Library page: https://bugbountylibrary.com/r/h1%3A207321
- Tags: area:oss domain:oss impact:data-leak kind:bounty platform:hackerone sev:medium tech:ruby technique:source-review vuln:info-disclosure vuln:memory-corruption

**Target:** mruby interpreter core (string.c comparison/aref/index functions)
**Root cause:** mrb_str_cmp_m calls the argument's overridable <=> and treats the returned mrb_value as a fixnum without mrb_fixnum_p check; since mrb_value is a union, an object pointer is reinterpreted as an integer.
**Steps:**
1. Override Integer#<=> to return its argument: `class Integer; def <=>(arg1); return arg1; end; end`
2. Call `s = "hello"; s.<=>(1)` so mrb_str_cmp_m invokes the overridden comparator
3. The returned string object is passed to mrb_fixnum(tmp), yielding the object's address, negated and returned as a fixnum
4. Observe output like `-69972254725992` (address `0x3fa3af631768`), varying per run due to ASLR
**How found:** Code review of string.c comparison functions, noticing arguments/return values treated as fixnums without type checks; reasoned that the union mrb_value lets an object pointer masquerade as an integer via an overridable <=>.
**Exploitation:** Attacker-controlled Ruby code reads the leaked pointer value from the comparison result, revealing a heap address of a string object and thereby defeating ASLR as a precursor to further memory-corruption exploitation.
**Insight:** In interpreters with tagged/union value types, audit every site that calls a user-overridable method and then assumes the return is a fixnum; overriding comparison operators to return objects turns these into pointer-leak oracles.

