CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/exploit/jsobfu.rb
Views: 1904
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
begin
8
msfbase = __FILE__
9
while File.symlink?(msfbase)
10
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
11
end
12
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))
13
require 'msfenv'
14
require 'rex'
15
require 'optparse'
16
require 'rex/exploitation/jsobfu'
17
18
module Jsobfu
19
class OptsConsole
20
def self.parse(args)
21
options = {}
22
parser = OptionParser.new do |opt|
23
opt.banner = "Usage: #{__FILE__} [options]"
24
opt.separator ''
25
opt.separator 'Specific options:'
26
27
opt.on('-t', '--iteration <Integer>', "Number of times to obfuscate the JavaScript") do |v|
28
options[:iteration] = v
29
end
30
31
opt.on('-i', '--input <String>', "The JavaScript file you want to obfuscate (default=1)") do |v|
32
options[:input] = v
33
end
34
35
opt.on('-o', '--output <String>', "Save the obfuscated file as") do |v|
36
options[:output] = v
37
end
38
39
opt.on('-p', '--preserved-identifiers id1,id2', 'The identifiers to preserve') do |v|
40
options[:preserved_identifiers] = v.split(',')
41
end
42
43
opt.on_tail('-h', '--help', 'Show this message') do
44
$stdout.puts opt
45
exit
46
end
47
end
48
49
parser.parse!(args)
50
51
if options.empty?
52
raise OptionParser::MissingArgument, 'No options set, try -h for usage'
53
elsif options[:iteration] && options[:iteration] !~ /^\d+$/
54
raise OptionParser::InvalidOption, "#{options[:format]} is not a number"
55
elsif !::File.exist?(options[:input].to_s)
56
raise OptionParser::InvalidOption, "Cannot find: #{options[:input]}"
57
end
58
59
options[:iteration] = 1 unless options[:iteration]
60
61
options
62
end
63
end
64
65
class Driver
66
def initialize
67
begin
68
@opts = OptsConsole.parse(ARGV)
69
rescue OptionParser::ParseError => e
70
$stderr.puts "[x] #{e.message}"
71
exit
72
end
73
end
74
75
def run
76
original_js = read_js(@opts[:input])
77
js = ::Rex::Exploitation::JSObfu.new(original_js)
78
obfu_opts = {}
79
obfu_opts.merge!(iterations: @opts[:iteration].to_i)
80
obfu_opts.merge!(preserved_identifiers: @opts[:preserved_identifiers] || [])
81
js.obfuscate(obfu_opts)
82
js = js.to_s
83
84
output_stream = $stdout
85
output_stream.binmode
86
output_stream.write js
87
$stderr.puts
88
89
if @opts[:output]
90
save_as(js, @opts[:output])
91
end
92
end
93
94
private
95
96
def read_js(path)
97
js = ::File.open(path, 'rb') { |f| js = f.read }
98
js
99
end
100
101
def save_as(js, outfile)
102
File.open(outfile, 'wb') do |f|
103
f.write(js)
104
end
105
106
$stderr.puts
107
$stderr.puts "File saved as: #{outfile}"
108
end
109
110
end
111
end
112
113
114
if __FILE__ == $PROGRAM_NAME
115
driver = Jsobfu::Driver.new
116
driver.run
117
end
118
rescue SignalException => e
119
puts("Aborted! #{e}")
120
end
121
122