390 likes | 685 Views
JavaScript Obfuscation. Facts and Fiction. Pedro Fortuna, Co-Founder and CTO AuditMark. Agenda. Part 1. Source code Obfuscation . Part 1 – Source Code obfuscation. Source Code Obfuscation. Lowers the code quality in terms of readability and maintainability
E N D
JavaScript Obfuscation Facts and Fiction Pedro Fortuna, Co-Founder and CTO AuditMark
Part 1 Source code Obfuscation Part 1 – Source Code obfuscation
Source Code Obfuscation • Lowers the code quality in terms of readability and maintainability • Goall: delay program understanding, hopefully to the point where the time needed for an expert professional to reverse it, clearly exceeds the useful lifetime of the program. • Different from Code Encryption • Source Code Obfuscation != Code Obfuscation
What is it good for? Good Evil Test the strength of security controls (IDS/IPS/WAFs/web filters) Hide malicious code Make it look like harmless code • Protect Intellectual Property (algorithms, data) • Prevent code theft and reuse • Enforce license agreements • Test the strength of security controls (IDS/IPS/WAFs/web filters)
Measuring Obfuscation • Potency • Resilience • Stealthiness • Execution Cost • Maintainability
Obfuscation PotencyMeasuring Obfuscation • Generate confusion
Obfuscation ResilienceMeasuring Obfuscation • Resistance to deobfuscation techniques, be it manual or automatic Rename all + whitespace removal String splitting
Static Code Analysisfor defeating obfuscation • 1. Parses the code • 2. Transforms it to fullfill a purpose • Usually to make it simpler => better performance • Simpler also fullfills reverse-engineering purpose • A compiler is a static code analyser • Things it can do • Constant folding, constant propagation • Remove (some) dead code • Automatic! • Next: an example
Dynamic Code Analysisfor defeating obfuscation • Analysis performed by executing the code • Retrieve information of the code while running • Resulting AST can be analysed using any method • Can be done in step by step debugging • How it can be used to defeat obfuscation • For the goal of understanding (one instance of) program execution • Not for the goal of retrieving the original source code (for code theft and reuse) • However it can be used to gain knowledge about the code that can be used to remove code checks or to simplify it for higher maintainability • May help breaking license agreements (piracy)
Obfuscation StealthinessMeasuring Obfuscation • How hard is to spot? • Avoid telltale indicators • eval() • unescape() • Large blocks of meaningless text • Example: Kolisar’s whitespace obfuscation • How to measure?
Obfuscation Execution CostMeasuring Obfuscation • Impact on performance • Impact on loading times • Impact on FPS
Obfuscation & MaintainabilityMeasuring Obfuscation • 1/potency • How easy to read after static code analysis ? • How segmented is the code ? • Higher maintainability => code theft and reuse
Part 2 practical examples Part 2– Practical Examples
A simple trick will do it eval( (function(....)) ); document.write(‘<textarea> (function(...)) </textarea>’);
Non alphanumeric Obfuscation • Encoding method using strictly non-alphanumeric symbols • Like other types of encoding (e.g. Compression) it uses eval • Example: alert(1)
How is that possible ? • Using type cohersion and browser quirks • We can obtain alphanumeric characters indirectly +[] -> 0 +!+[] -> 1 +!+[]+!+[] -> 2 Easy to get any number +”1” -> 1 Type cohersion to number “”+1 = “1” Type cohersion to string How to get letters? +”a” -> NaN +”a”+”” -> “NaN” (+”a”+””)[0] -> “N” Ok, but now without alphanumerics: (+”a”+””)[+[]] -> “N” How to get an “a” ? ![] -> false ![]+“” -> “false” (![]+””)[1] -> “a” (![]+””)[+!+[]] (+(![]+"")[+!+[]]+””)[+[]] -> “N” eval( (![]+"")[1]+"lert(1)");
Wait... where’s the eval ? • eval() is not the only way to eval() ! • You have 4 or 5 methods more • Example: Array.constructor(alert(1))() • []["sort"]["constructor"]("alert(1)")() • Dot notation • Strings !
Non alphanumeric Obfuscation • 100% potent • 0% stealthy • High execution cost • eval is slower • File is much larger => slower loading times • Does not work in all browsersProblema: • What about resilience ?
Function outlining • Creates new functions out of statements in the code • Statements are randomly selected • New functions are added to different scopes • Functions are added to object literals to reduce the scope pollution • Increases complexity by using multiple namespaces • Function reordering is possible
Function outlining • Creates new functions out of statements in the code • Statements are randomly selected
Function outlining • New functions are added to different scopes • Functions are added to object literals to reduce the scope pollution • Increases complexity by using multiple namespaces • Function reordering is possible
Deadcode insertion (with predicate Opaques) • Insert code to increase confusion • It isn’t executed
Deadcode insertion (with predicate Opaques) • Randomly injected (++potency) • Increase complexity of control flow (++potency) • Some places are avoided (e.g. loops) • Dummy statements created out of own code (++stealth, ++potency) • Opaque predicates • Not removable using Static Code Analysis • Predicates injected are similar to ones found in the original source
JavaScript Obfuscation • It can really help prevent code theft and reuse • Buys you time • You can always try to make a request to the server side and process it there, but sometimes that is not feasiable • Widgets • Mobile Apps • Standalone, offline-playable games • Windows 8 Apps made with WinJS • Prefer transformations with negligible execution cost • Prefer transformations with high resilience • Sometimes it is a trial and error experience • Code execution control is a great allied
Contact Information Pedro Fortuna Owner & Co-Founder & CTO pedro.fortuna@auditmark.com Phone: +351 917331552 Lisbon office Startup Lisboa Rua da prata, 121 5A 1100-415 Lisbon, Portugal Porto - Headquarters Edifício Central da UPTEC Rua Alfredo Allen, 455 4200-135 Porto, Portugal