11# -*- coding: binary -*-
22
33require 'rex/text'
4+ require 'rex/random_identifier_generator'
45require 'rkelly'
56
67module Rex
@@ -47,6 +48,15 @@ module Exploitation
4748#
4849class JSObfu
4950
51+ # these keywords should never be used as a random var name
52+ # source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words
53+ RESERVED_KEYWORDS = %w(
54+ break case catch continue debugger default delete do else finally
55+ for function if in instanceof new return switch this throw try
56+ typeof var void while with class enum export extends import super
57+ implements interface let package private protected public static yield
58+ )
59+
5060 #
5161 # Abstract Syntax Tree generated by RKelly::Parser#parse
5262 #
@@ -60,6 +70,11 @@ def initialize(code)
6070 @funcs = { }
6171 @vars = { }
6272 @debug = false
73+ @rand_gen = Rex ::RandomIdentifierGenerator . new (
74+ :max_length => 15 ,
75+ :first_char_set => Rex ::Text ::Alpha +"_$" ,
76+ :char_set => Rex ::Text ::AlphaNumeric +"_$"
77+ )
6378 end
6479
6580 #
@@ -107,8 +122,23 @@ def obfuscate
107122 obfuscate_r ( @ast )
108123 end
109124
125+ # @return [String] a unique random var name that is not a reserved keyword
126+ def random_var_name
127+ loop do
128+ text = random_string
129+ unless @vars . has_value? ( text ) or RESERVED_KEYWORDS . include? ( text )
130+ return text
131+ end
132+ end
133+ end
134+
110135protected
111136
137+ # @return [String] a random string
138+ def random_string
139+ @rand_gen . generate
140+ end
141+
112142 #
113143 # Recursive method to obfuscate the given +ast+.
114144 #
@@ -152,14 +182,12 @@ def obfuscate_r(ast)
152182 # Variables
153183 when ::RKelly ::Nodes ::VarDeclNode
154184 if @vars [ node . name ] . nil?
155- #@vars[node.name] = "var_#{Rex::Text.rand_text_alpha(3+rand(12))}_#{node.name}"
156- @vars [ node . name ] = "#{ Rex ::Text . rand_text_alpha ( 3 +rand ( 12 ) ) } "
185+ @vars [ node . name ] = random_var_name
157186 end
158187 node . name = @vars [ node . name ]
159188 when ::RKelly ::Nodes ::ParameterNode
160189 if @vars [ node . value ] . nil?
161- #@vars[node.value] = "param_#{Rex::Text.rand_text_alpha(3+rand(12))}_#{node.value}"
162- @vars [ node . value ] = "#{ Rex ::Text . rand_text_alpha ( 3 +rand ( 12 ) ) } "
190+ @vars [ node . value ] = random_var_name
163191 end
164192 node . value = @vars [ node . value ]
165193 when ::RKelly ::Nodes ::ResolveNode
@@ -181,8 +209,7 @@ def obfuscate_r(ast)
181209 # Functions can also act as objects, so store them in the vars
182210 # and the functions list so we can replace them in both places
183211 if @funcs [ node . value ] . nil? and not @funcs . values . include? ( node . value )
184- #@funcs[node.value] = "func_#{Rex::Text.rand_text_alpha(3+rand(12))}_#{node.value}"
185- @funcs [ node . value ] = "#{ Rex ::Text . rand_text_alpha ( 3 +rand ( 12 ) ) } "
212+ @funcs [ node . value ] = random_var_name
186213 if @vars [ node . value ] . nil?
187214 @vars [ node . value ] = @funcs [ node . value ]
188215 end
0 commit comments