Novel Approach to JS Obfuscation by Inter(pell | pol)ation
Live Example: https://grayleonard.github.io/interpellate/
I shall then suggest that ideology ‘acts’ or ‘functions’ in such a way that it ‘recruits’ subjects among the individuals (it recruits them all), or ‘transforms’ the individuals into subjects (it transforms them all) by that very precise operation which I have called interpellation or hailing, and which can be imagined along the lines of the most commonplace everyday police (or other) hailing: ‘Hey, you there!’
- Louis Althusser, "Ideology and Ideological State Apparatuses", 1970
Interpellate dynamically inserts a self-executing stub into any - ideally large - minified javascript library (tested with jQuery.min.js, Facebook's sdk.js, and Google's ga.js). The stub contains pointers to character locations in the library and, using arguments.callee.caller, which returns source code without any network calls, the stub self-referentially rebuilds the injected javascript and then executes it. This is intended for small javascript snippets that are typically included inside of <script> tags or from a small file.
It takes the three file locations for arguments:
- The 'policeman', or the library to merge into (examples in police/)
- The 'individual', which contains the code to execute (examples in individuals/)
- The 'street', the self-executing stub (examples in streets/, streets/template.min.js is provided & recommended)
Here is the process in pseudocode:
insert(street, policeman) //the initial insertion of the stub
individual = 'alert(1);'
until pos_string == individual:
forEach(char in individual) -> //'a', 'l', 'e', and so on
pos_array += rand_pos(char, policeman)// get random character position in policeman
insert(pos_array, policeman) // insert new array into policeman
pos_string = get_chars(pos_array) // searches for chars in the updated policeman
Requirements: Node.js 0.10+
Download with git clone https://github.com/grayleonard/interpellate.git
Usage: ./index.js [options]
Options:
-h, --help output usage information
-V, --version output the version number
-p, --policeman <path> Policeman that hails individual
-i, --individual <path> Individual to interpellate
-s, --street <path> Street that is embedded into policeman, executes individual
-o, --output <path> Interpellated file output
-v, --verbose Verbose logging
Example Use:
./index.js -p police/jquery.min.js -i individuals/alert.js -s streets/template.min.js -o subjects/jquery_alert.js -v
Output:
[info] Inserting street ...
[info] Inserted street after the 29th FunctionDeclaration
[info] Finding char locations ...
[info] New iteration: alert(1)b
[info] New iteration: rl{p.&=ba
[info] New iteration: alerf(1ro
...
[info] New iteration: paerts1cb
[info] New iteration: alert(1);
[info] Found match, writing to file subjects/jquery_alert.js
The file from this example is provided at subjects/jquery_alert.js and you can test it immediately by opening test.html in the root directory of this repo. Tested as of now in latest Chrome and Safari.
Alternatively, visit https://grayleonard.github.io/interpellate/ for a live example.
It works with some libraries better than others, so you may need to retry a few times before it works.
