jssuicide:usingjavascriptsecurityfeaturesto# killjssecurity · bypass#1#k#prototype#overriding...

57
JS Suicide: Using JavaScript Security Features to Kill JS Security 1 Ahamed Nafeez

Upload: others

Post on 16-Oct-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

JS  Suicide:  Using  JavaScript  Security  Features  to  Kill  JS  Security    

1

Ahamed  Nafeez  

Page 2: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

AgendaJavaScript  of  all  things  !Objects  and  ECMAScript  5  !The  Principle  of  Unobtrusive  JavaScript  !The  sad  story  of  OWASP  CSRFGuard  !DOM  Clobbering  !Hunting  down  insecure  DOM  Properties  !Domstorm  v0.9  Beta  !

Page 3: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

What  to  expect  today?

This  talk  is  about:  • Using  JavaScript’s  features  to  attack  its  implementations.  • Bypassing  OWASP  CSRFGuard’s  protection.  • DOM  Clobbering.  !This  talk  is  NOT  about,  how  to  do  • Cross  site  scripting  • Cross  site  request  forgery  • Or  the  usual  stuff  you  hear  in  JS  Security  like  eval,  Global  Objects  etc.

Page 4: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

#whoami!Ahamed  Nafeez  !Security  Engineer  by  day,  with  above  average  interest  in  Web  and  Networks.  !I  believe,  Defending  and  Building  secure  software  is  harder  than  attacking.  !blog.skepticfx.com  !

This  talk  does  not  represent  the  view  of  my  employer.  !

Page 5: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

JavaScript  of  all  things

Page 6: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Enough  JS  Primer  for  today

Dynamic  language  !Object-­‐based  !Functions  are  first  class  citizens  

Page 7: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Native  Objects

Page 8: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Object  Array  

Number

Page 9: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Host  Objects

Page 10: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

DOM  -­‐  Browsers  http,  dns  -­‐  Nodejs

Page 11: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

ECMAScript  5

Page 12: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Tamper-­‐Proof  Objects  !

var  point  =   {  a:  1,  b:  2  }

Page 13: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Object.defineProperty(point,  'a',  {  get:  function()  

{return  'Always  faked'}  });

Page 14: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

point.a;  //  ‘Always  Faked’  point.a  =  200;  

point.a;  //  ‘Always  Faked’

Page 15: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Object.preventExtensions(point)  !

point.c  =  3;

//  Error:  Cannot  set  Property

Page 16: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Object.seal(point)  !

delete  point.a;

//  Error:  Cannot  delete  Property

Page 17: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Object.freeze(point)  !

point.a  =  100;

//  Error:  Cannot  change  Property

Page 18: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

The  principle  of  unobtrusive  JavaScript

Page 19: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

19

Going  Unobtrusive

Page 20: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Almost  Static  HTMLDynamic  Data  over  JavaScript  

via  XHR,  JSON  etc

Page 21: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

21

Page 22: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Cached  HTML  pages  Non-­‐Cached  JavaScript  pages

Page 23: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Where  do  I  put  my  dynamic  +  secret  artifacts?

Page 24: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

OWASP  CSRFGuard

Synchroniser  token  pattern.  !Injects  ANTI-­‐CSRF  tokens  in  to  pages  dynamically  !Completely  compatible  with  the  principle  of  UnObtrusive  JavaScript

Page 25: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Where  did  they  keep  their  tokens?

Page 26: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it
Page 27: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Smells  fishy  !

Page 28: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

An  attacker  could  load  this  JS  file  from  a  Cross-­‐Domain  website  and  steal  this  

token.

Page 29: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

The  library  did  protect  against  that

Page 30: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Lets  introspect  isValidDomain()

If  this  returns  True,  the  check  is  bypassed.

Page 31: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Custom  String.prototype

Page 32: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Bypass  1  -­‐  Prototype  Overriding

Always  return  True

Freeze  the  String.prototype  Object,  So  CSRFGuard  cannot  redefine  it.

override.js

Page 33: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

33

Bypass  1  -­‐  Continued  .  .  .

Load  the  CSRFGuard  JS  File  from  good.com

Walk  the  DOM  and  read  the  CSRF  Token  injected  by  the  library.

Page 34: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Lets  attempt  to  fix  this

Object.isFrozen()  tells  whether  an  Object  is  already  frozen.

Page 35: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Did  you  know?  !

   

Object.isFrozen()  can  be  spoofed  as  well?

Page 36: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

36

Attacker  can  return,  ‘false’  always  

Page 37: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

37

Bypassing  the  isFrozen()  Fix  

Page 38: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

38

!

!

Lets  try  another  way  to  bypass  this  whole  situation.    

!

Just  for  Fun.

Page 39: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

39

Revisiting  the  Check

The  whole  check  depends  on  the  value  of  document.domain

Page 40: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Wait  !  document.domain  is  a  lie

Page 41: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Bypass  2

41

Make  document.domain    always  return  good.com

Page 42: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

How  to  deal  with  this  situation?

Page 43: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Do  not  Hard  Code  the  Dynamic  +  Secret  artifacts.

1.  Embed  them  inside  your  DOM  such  as  META  tags  and  read  from  JS

2.  Send  an  XHR  request  and  read  it.  So  the  token  is  protected  by  Same  Origin  PolicyOR

Page 44: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Upgrade  to  CSRFGuard  3.1

Page 45: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

DOM  Clobbering

Page 46: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Names  and  IDs  of  form  controls  are  treated  as  properties  to  the  FORM  Element.

Page 47: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Think  about  JS  Frame  Busters

Used  to  prevent  against  UI  Redressing  attacks.  Some  people  still  use  this    alongside,  

the    X-­‐Frame-­‐Options  header.

Page 48: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it
Page 49: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

If  an  Attacker  can  control  form  fields

Page 50: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

The  DOM  is  a  Mess  !  !

@garethheyes    -­‐    http://www.thespanner.co.uk/2013/05/16/dom-­‐clobbering/

Page 51: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Hunting  down  Objects  which  can  be  tampered

Page 52: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

52

Object.getOwnPropertyDescriptor

Look  for  the  ‘configurable’  property

Page 53: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

53

Location  Properties  in  Chrome

Page 54: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

54

Domstorm  !

v0.9  Beta  -­‐  http://domstorm.skepticfx.com  Github  -­‐  https://github.com/skepticfx/domstorm  

!A  tool  /  dashboard  for  testing  and  collecting  all  DOM  

related  shenanigans.  !

Similar  to  Shazzer,  but  for  the  DOM.  !

Page 55: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

Things  to  keep  in  mind

Today,  a  developer  can  only  rely  on location.href,  as  the  only  trusted  source  of  location.  !Every  other  location  properties  can  be  spoofed  and  played  around  with.  !You  can  try  fuzzing  various  different  properties  and  use  them  in  your  pen  tests  /  research  accordingly.  

Page 56: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

You  should  followMario,  @0x6D6172696F  !Gareth  Heyes,  @garethheyes    !Yosuke  Hasegawa,  @hasegawayosuke    !And  a  few  more,  that  I  don’t  have  space  to  mention  here.  !!!

!Klapspil  

!

Page 57: JSSuicide:UsingJavaScriptSecurityFeaturesto# KillJSSecurity · Bypass#1#K#Prototype#Overriding Always#return#True Freeze#the#String.prototype#Object,# So#CSRFGuard#cannot#redefine#it

THANK YOU ! @SKEPTIC_FX ! KEEP STORMING THE DOM :)