Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/tools/exploit/java_deserializer.rb
Views: 11768
#!/usr/bin/env ruby12##3# This module requires Metasploit: https://metasploit.com/download4# Current source: https://github.com/rapid7/metasploit-framework5##6begin7msf_base = __FILE__8while File.symlink?(msf_base)9msf_base = File.expand_path(File.readlink(msf_base), File.dirname(msf_base))10end1112$:.unshift(File.expand_path(File.join(File.dirname(msf_base), '..', '..', 'lib')))13require 'rex/java/serialization'14require 'pp'15require 'optparse'1617# This class allows to deserialize Java Streams from18# files19class JavaDeserializer2021# @!attribute file22# @return [String] the file's path to deserialize23attr_accessor :file2425# @param file [String] the file's path to deserialize26def initialize(file = nil)27self.file = file28end2930# Deserializes a Java stream from a file and prints the result.31#32# @return [Rex::Java::Serialization::Model::Stream] if succeeds33# @return [nil] if error34def run(options = {})35if file.nil?36print_error("file path with serialized java stream required")37return38end3940print_status("Deserializing...")41print_line4243begin44f = File.new(file, 'rb')45stream = Rex::Java::Serialization::Model::Stream.decode(f)46f.close47rescue ::Exception => e48print_exception(e)49return50end5152if options[:array]53print_array(stream.contents[options[:array].to_i])54elsif options[:object]55print_object(stream.contents[options[:object].to_i])56else57puts stream58end59end6061private6263# @param msg [String] String to print as a status message.64def print_status(msg='')65$stdout.puts "[*] #{msg}"66end6768# @param msg [String] String to print as a error message.69def print_error(msg='')70$stdout.puts "[-] #{msg}"71end7273# @param e [Exception] Exception to print74def print_exception(e)75print_error(e.message)76e.backtrace.each do |line|77$stdout.puts("\t#{line}")78end79end8081def print_line82$stdout.puts("\n")83end8485# @param [Rex::Java::Serialization::Model::NewObject] obj the object to print86# @param [Integer] level the indentation level when printing super classes87def print_object(obj, level = 0)88prefix = " " * level89if obj.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc90puts "#{prefix}Object Class Description:"91print_class(obj.class_desc.description, level + 1)92else93puts "#{prefix}Object Class Description: #{obj.class_desc.description}"94end95puts "#{prefix}Object Data: #{obj.class_data}"96end9798# @param [Rex::Java::Serialization::Model::NewClassDesc] c the class to print99# @param [Integer] level the indentation level when printing super classes100def print_class(c, level = 0)101prefix = " " * level102puts "#{prefix}Class Name: #{c.class_name}"103puts "#{prefix}Serial Version: #{c.serial_version}"104puts "#{prefix}Flags: #{c.flags}"105puts "#{prefix}Fields ##{c.fields.length}"106c.fields.each do |f|107puts "#{prefix}Field: #{f}"108end109puts "#{prefix}Class Annotations ##{c.class_annotation.contents.length}"110c.class_annotation.contents.each do |c|111puts "#{prefix}Annotation: #{c}"112end113puts "#{prefix}Super Class: #{c.super_class}"114if c.super_class.description.class == Rex::Java::Serialization::Model::NewClassDesc115print_class(c.super_class.description, level + 1)116end117end118119# @param [Rex::Java::Serialization::Model::NewArray] arr the array to print120# @param [Integer] level the indentation level when printing super classes121def print_array(arr, level = 0)122prefix = " " * level123if arr.array_description.description.class == Rex::Java::Serialization::Model::NewClassDesc124puts "#{prefix}Array Description"125print_class(arr.array_description.description, 1)126else127puts "#{prefix}Array Description: #{arr.array_description.description}"128end129puts "#{prefix}Array Type: #{arr.type}"130puts "#{prefix}Array Values ##{arr.values.length}"131arr.values.each do |v|132puts "Array value: #{prefix}#{v} (#{v.class})"133if v.class == Rex::Java::Serialization::Model::NewObject134print_object(v, level + 1)135end136end137end138end139140if __FILE__ == $PROGRAM_NAME141142options = {}143OptionParser.new do |opts|144opts.banner = "Usage: java_deserializer.rb <file> [option]"145146opts.on("-aID", "--array=ID", "Print detailed information about content array") do |id|147options[:array] = id148end149150opts.on("-oID", "--object=ID", "Print detailed information about content object") do |id|151options[:object] = id152end153154opts.on("-h", "--help", "Prints this help") do155puts opts156exit157end158end.parse!159160if options.length > 1161$stdout.puts "[-] Don't provide more than one option"162exit163end164165deserializer = JavaDeserializer.new(ARGV[0])166deserializer.run(options)167end168rescue SignalException => e169puts("Aborted! #{e}")170end171172173