Class: OneGadget::Gadget::Gadget
- Inherits:
-
Object
- Object
- OneGadget::Gadget::Gadget
- Defined in:
- lib/one_gadget/gadget.rb
Overview
Information of a gadget.
Instance Attribute Summary collapse
-
#base ⇒ Integer
Base address of libc.
-
#closed_fds ⇒ Array<String>
readonly
Where each descriptor this gadget closes before the exec is read from, in the order it closes them (see #caveats).
-
#constraints ⇒ Array<String>
readonly
The constraints need for this gadget.
-
#effect ⇒ String
readonly
The final result of this gadget.
-
#offset ⇒ Integer
readonly
The gadget's address offset.
Instance Method Summary collapse
-
#caveats ⇒ Array<String>
What the gadget costs the caller beyond its constraints: a descriptor it closes on the way to the exec.
-
#initialize(offset, **options) ⇒ Gadget
constructor
Initialize method of Gadget instance.
-
#inspect ⇒ String
Returns a human-readable, colorized representation of this gadget, showing its address followed by the effect and constraints.
-
#met_by?(other) ⇒ Boolean
Whether
otherasks for everything this gadget asks for, so listing this one beside it tells the reader nothing new. -
#score ⇒ Float
The success probability of the constraints.
-
#to_json ⇒ String
Serializes this gadget into a JSON string.
-
#to_obj ⇒ Hash{Symbol => Integer, String, Array<String>, Array<Integer>}
Converts this gadget into a plain hash, suitable for serialization.
-
#value ⇒ Integer
Returns
baseplusoffset.
Constructor Details
#initialize(offset, **options) ⇒ Gadget
Initialize method of OneGadget::Gadget::Gadget instance.
32 33 34 35 36 37 38 |
# File 'lib/one_gadget/gadget.rb', line 32 def initialize(offset, **) @base = 0 @offset = offset @constraints = prune_settled([:constraints] || []) @effect = [:effect] || '' @closed_fds = [:closed_fds] || [] end |
Instance Attribute Details
#base ⇒ Integer
Returns Base address of libc. Default: 0.
15 16 17 |
# File 'lib/one_gadget/gadget.rb', line 15 def base @base end |
#closed_fds ⇒ Array<String> (readonly)
Returns Where each descriptor this gadget closes before the exec is read from, in the order it closes them (see #caveats).
24 25 26 |
# File 'lib/one_gadget/gadget.rb', line 24 def closed_fds @closed_fds end |
#constraints ⇒ Array<String> (readonly)
Returns The constraints need for this gadget.
19 20 21 |
# File 'lib/one_gadget/gadget.rb', line 19 def constraints @constraints end |
#effect ⇒ String (readonly)
Returns The final result of this gadget.
21 22 23 |
# File 'lib/one_gadget/gadget.rb', line 21 def effect @effect end |
#offset ⇒ Integer (readonly)
Returns The gadget's address offset.
17 18 19 |
# File 'lib/one_gadget/gadget.rb', line 17 def offset @offset end |
Instance Method Details
#caveats ⇒ Array<String>
What the gadget costs the caller beyond its constraints: a descriptor it closes on the way to the exec. Each line names the close itself, so it reads as the code does and can be matched exactly, and says what the value must avoid for the spawned shell to keep its I/O.
47 48 49 50 51 52 |
# File 'lib/one_gadget/gadget.rb', line 47 def caveats closed_fds.map do |fd| "close(#{fd}): prevent it from being 0 (stdin) or 1 (stdout) to sound " \ 'an interactive shell.' end end |
#inspect ⇒ String
Returns a human-readable, colorized representation of this gadget, showing its address followed by the effect and constraints.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/one_gadget/gadget.rb', line 57 def inspect str = "#{OneGadget::Helper.hex(value)} #{effect}\n" unless constraints.empty? str += "#{OneGadget::Helper.colorize('constraints')}:\n " str += merge_constraints.join("\n ") end unless caveats.empty? str += "\n" unless constraints.empty? str += "#{OneGadget::Helper.colorize('caveats')}:\n " str += caveats.join("\n ") end str.gsub!(/0x[\da-f]+/) { |s| OneGadget::Helper.colorize(s, sev: :integer) } OneGadget::ABI.all.each do |reg| str.gsub!(/([^\w])(#{reg})([^\w])/, "\\1#{OneGadget::Helper.colorize('\2', sev: :reg)}\\3") end "#{str}\n" end |
#met_by?(other) ⇒ Boolean
Whether other asks for everything this gadget asks for, so listing this
one beside it tells the reader nothing new. Each constraint here has to be
met by +other+'s list: named there, or -- for one that offers several
options -- an option of it required there outright.
115 116 117 118 119 120 |
# File 'lib/one_gadget/gadget.rb', line 115 def met_by?(other) constraints.all? do |con| other.constraints.include?(con) || con.split(DISJUNCTION).any? { |option| other.constraints.include?(option) } end end |
#score ⇒ Float
Returns The success probability of the constraints.
102 103 104 |
# File 'lib/one_gadget/gadget.rb', line 102 def score @score ||= constraints.reduce(1.0) { |s, c| s * calculate_score(c) } end |
#to_json ⇒ String
Serializes this gadget into a JSON string.
90 91 92 |
# File 'lib/one_gadget/gadget.rb', line 90 def to_json(*) to_obj.to_json end |
#to_obj ⇒ Hash{Symbol => Integer, String, Array<String>, Array<Integer>}
Converts this gadget into a plain hash, suitable for serialization.
81 82 83 84 85 86 |
# File 'lib/one_gadget/gadget.rb', line 81 def to_obj obj = { value:, effect:, constraints: } return obj if caveats.empty? obj.merge(closed_fds:, caveats:) end |
#value ⇒ Integer
Returns base plus offset.
96 97 98 |
# File 'lib/one_gadget/gadget.rb', line 96 def value base + offset end |