Class: Rex::Exploitation::JSObfu
- Inherits:
-
Object
- Object
- Rex::Exploitation::JSObfu
- Defined in:
- lib/rex/exploitation/jsobfu.rb
Overview
Obfuscate JavaScript by randomizing as much as possible and removing easily-signaturable string constants.
Example:
js = ::Rex::Exploitation::JSObfu.new %Q|
var a = "0\\612\\063\\x34\\x35\\x36\\x37\\x38\\u0039";
var b = { foo : "foo", bar : "bar" }
alert(a);
alert(b.foo);
|
js.obfuscate
puts js
Example Output:
var VwxvESbCgv = String.fromCharCode(0x30,0x31,062,063,064,53,0x36,067,070,0x39);
var ToWZPn = {
"\146\157\x6f": (function () { var yDyv="o",YnCL="o",Qcsa="f"; return Qcsa+YnCL+yDyv })(),
"\142ar": String.fromCharCode(0142,97,0162)
};
alert(VwxvESbCgv);
alert(ToWZPn.foo);
NOTE: Variables MUST be declared with a ‘var’ statement BEFORE first use (or not at all) for this to generate correct code! If variables are not declared they will not be randomized but the generated code will be correct.
Bad Example Javascript:
a = "asdf"; // this variable hasn't been declared and will not be randomized
var a;
alert(a); // real js engines will alert "asdf" here
Bad Example Obfuscated:
a = (function () { var hpHu="f",oyTm="asd"; return oyTm+hpHu })();
var zSrnHpEfJZtg;
alert(zSrnHpEfJZtg);
Notice that the first usage of a
(before it was declared) is not randomized. Thus, the obfuscated version will alert ‘undefined’ instead of “asdf”.
Constant Summary collapse
- RESERVED_KEYWORDS =
these keywords should never be used as a random var name source: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words
%w( break case catch continue debugger default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with class enum export extends import super implements interface let package private protected public static yield )
Instance Attribute Summary collapse
-
#ast ⇒ Object
readonly
Abstract Syntax Tree generated by RKelly::Parser#parse.
Instance Method Summary collapse
-
#<<(str) ⇒ Object
Add
str
to the un-obfuscated code. -
#initialize(code) ⇒ JSObfu
constructor
Saves
code
for later obfuscation with #obfuscate. -
#obfuscate ⇒ Object
Parse and obfuscate.
-
#random_var_name ⇒ String
A unique random var name that is not a reserved keyword.
-
#sym(lookup) ⇒ Object
Return the obfuscated name of a symbol.
-
#to_s ⇒ Object
Return the (possibly obfuscated) code as a string.
Constructor Details
#initialize(code) ⇒ JSObfu
Saves code
for later obfuscation with #obfuscate
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rex/exploitation/jsobfu.rb', line 68 def initialize(code) @code = code @funcs = {} @vars = {} @debug = false @rand_gen = Rex::RandomIdentifierGenerator.new( :max_length => 15, :first_char_set => Rex::Text::Alpha+"_$", :char_set => Rex::Text::AlphaNumeric+"_$" ) end |
Instance Attribute Details
#ast ⇒ Object (readonly)
Abstract Syntax Tree generated by RKelly::Parser#parse
63 64 65 |
# File 'lib/rex/exploitation/jsobfu.rb', line 63 def ast @ast end |
Instance Method Details
#<<(str) ⇒ Object
Add str
to the un-obfuscated code.
Calling this method after #obfuscate is undefined
85 86 87 |
# File 'lib/rex/exploitation/jsobfu.rb', line 85 def <<(str) @code << str end |
#obfuscate ⇒ Object
Parse and obfuscate
120 121 122 123 |
# File 'lib/rex/exploitation/jsobfu.rb', line 120 def obfuscate parse obfuscate_r(@ast) end |
#random_var_name ⇒ String
Returns a unique random var name that is not a reserved keyword.
126 127 128 129 130 131 132 133 |
# File 'lib/rex/exploitation/jsobfu.rb', line 126 def random_var_name loop do text = random_string unless @vars.has_value?(text) or RESERVED_KEYWORDS.include?(text) return text end end end |
#sym(lookup) ⇒ Object
Return the obfuscated name of a symbol
You MUST call #obfuscate before this method!
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rex/exploitation/jsobfu.rb', line 106 def sym(lookup) if @vars[lookup] ret = @vars[lookup] elsif @funcs[lookup] ret = @funcs[lookup] else ret = lookup end ret end |
#to_s ⇒ Object
Return the (possibly obfuscated) code as a string.
If #obfuscate has not been called before this, returns the parsed, unobfuscated code. This can be useful for example to remove comments and standardize spacing.
96 97 98 99 |
# File 'lib/rex/exploitation/jsobfu.rb', line 96 def to_s parse if not @ast @ast.to_ecma end |